Gputils fejlesztés

Pár hónapja nekiláttam foltokat patch-eket küldözgetni a gputils fejlesztőinek. Tettem mindezt azzal a szándékkal hogy hozzáadjam az újabb Microchip MCU-k támogatását, ugyanis "kissé" el voltak maradva.

Elfogadták a foltokat patch-eket egyiket a másik után. A vége az lett hogy Borut Ražem kezdte sokallni a munkát ami miattam keletkezett. Kiderült hogy csak ketten voltak aktív fejlesztők. (Valahogy azt képzeltem hogy jóval többen vannak.) Mivel már nem voltam ismeretlen az sdcc-hez küldött foltjaim patch-eim miatt, megkérdezte a társát (Marko Kohtala) hogy mit szólna ha én is kapnék admin jogokat. Ő annyit írt erre hogy: Rajta! Egy ideje már hárman vagyunk fejlesztők. Az elején ebből támadt is gondom. Azóta nagyjából hozzáadtam az újabb processzorok támogatását és írtam két komolyabb segédprogramot perl-ben. Biztosan vannak akik megmosolyogják ezt az egészet, de nekem jólesett hogy értékelték a munkámat.

Hozzászólások

Mi az hogy normális hely? Egyáltalán mi a normális (átlagos, megszokott, követendő)? Valahogy úgy érzem hogy az amit ma ebben a világban - főleg kis hazánkban - kezdenek normálisnak elfogadtatni (lopni, csalni, hazudni, letaposni, kihasználni a másikat, egyáltalán aljasnak [politikusnak] lenni) az visszataszító számomra. Talán nem kéne követnem a híreket, de nem jó tájékozatlannak lenni.

En most megint leszokoban vagyok a hirekrol. 3 evig jol ment az, hogy a twitterrol/facebookrol tajekozodtam az aktualis hirekrol, es magamtol nem pottyentettem be az index.hu/origo.hu-t a cimsorba. Most tavalyelott ota visszaestem. Sok. Frusztral.
--

Ki oda vagyik, hol szall a galamb, elszalasztja a kincset itt alant. | Gentoo Portal 

Elég idegesítő ez a világ. Valamikor még az Antall Jóska idejében azt mondtam az elégedetlenkedőknek hogy: Várjatok csak, eljön az az idő amikor ezt a mai rosszat aranykornak fogjuk nevezni. Az idővonal jelen részéről nézve annak tűnik. Egyszer talán leérünk a gödör aljára és onnantól kezdve csak fölfelé találunk utat. (Csak nehogy bányász legyen az aki a mostani hülye focistát leváltja.)

"folt", omg. hivjuk mar annak, ami: patch.

Ebből lehetne jókora hitvitát kerekíteni. Fene tudja, szeretnék magyarul írni. Itt állandóan csak "detektálnak". A cikkírónak valószínűleg letörne a keze ha le kéne írnia ezeket: Észlelnek, érzékelnek, felfedeznek, látnak vagy csak találnak. Emitt főleg a tudományos cikkekben a mánia: flexibilis. Nem rugalmas, hajlékony vagy alkalmazkodó. Valami rémséges tett lenne magyarul leírni? Szegény Kölcsey Ferenc foroghat a sírjában. Nem tartom magamat maradinak, de mi magyarok egymás között miért nem magyarul közöljük a gondolatainkat? Persze akadnak olyan idegen szavak amiket csak körülírással lehetne magyarul megnevezni. A patch szót nem tartom ilyennek. (Ezzel nem akarlak megbántani.)

Peldaul egy security patch biztonsagi lyukat (security hole) foltoz be. Akar jo is lehet ra a folt.

De egyebkent erdekelne a velemenyed. Ha valamiert mindenkeppen le kellene a kifejezest forditanod, akkor mire forditanad? Komolyan erdekel a valasz.
--

Ki oda vagyik, hol szall a galamb, elszalasztja a kincset itt alant. | Gentoo Portal 

A "detektál", "flexibilis" szavak már magyarul vannak, azokra nyilván lehet szövegkörnyezetbe illeszthető szinonimákat találni. Viszont a patch szó által ebben a szövegkörnyezetben hordozott jelentésére nincs megfelelő magyar fordítás, és ezen az nem változtat, hogy más jelentésére van. Vagyis amikor foltnak fordítod, információ veszik el, mert a folt nem rendelkezik azzal a jelentéssel, amivel angolban a patch. Vagyis ahhoz, hogy a szöveg érthető legyen, az olvasónak fejben vissza kell fordítania a folt szót patch-re, és utána tudja csak megtalálni a szövegkörnyezetbe illő jelentését.

A bug szót sem szokás bogárnak fordítani, pont azért, mert angolban a bug szó hordozza a programhiba jelentést, de magyarban a bogár nem.

A patchnak nincs nagyon plusz jelentesarnyalata, mert a patch - amennyire tudom - az angolban is kozvetlenul az eredeti jelentes felhasznlasaval jott letre, tehat nem - magyar kifejezessel elve - egy azonos alaku, de eltero jelentesu szo szuletett, hanem egy plusz jelentest adtak a meglevohoz, ami tobbe-kevesbe korrelal vele.

Nem az tortent, mint peldaul a cat paranccsal (ami egyebkent rovidites, de ezt most hagyjuk figylelmen kivul), ahol a macska jelenteshez jott egy totalisan eltero is.

Az, hogy magyarban jelenleg egyik sem hordozza a plusz jelentest, az nem jelenti azt, hogy megfelelo szocializacio utan ne hordozhatna.

Ott van peldaul a mirelit szavunk. Anno ez egy cegnev volt, nem volt olyan jelentese, hogy fagyasztott arucikk, sot korabban a szonak nem volt jelentese sem nalunk. Aztan lett, mert a Mirelit - meglepo modon - fagyasztott cuccokat arult.

Mondjuk a bug egyebkent jogos, ott nincs kozvetlen jelentesbovites.

--

Ki oda vagyik, hol szall a galamb, elszalasztja a kincset itt alant. | Gentoo Portal 

Szerintem azon múlik, hogy van-e már az adott dolognak a magyarban használt elnevezése, vagy nincs. A patch szót magyar nyelvi környezetben is használjuk, ezért nem valószínű, hogy egy másik elnevezés elterjedjen. Viszont a fagyasztott élelmiszer kifejezés nem volt elég egyszerű és kifejező, így elterjedhetett a mirelit szó.

Régen nem írtam már ide. Tavaly úgy alakult a helyzet hogy Marko Kohtala eltűnt valahová. Idén januárban pedig jött az a hír hogy Borut Ražem meghalt. Így aztán gyakorlatilag magamra maradtam a gputils karbantartásával. Ez mostanában kimerül az újabb MCU-k hozzáadásában és a html-help oldal frissítésében. Szerencsére ezekre a munkákra írtam egy-egy jókora méretű perl alapú scriptet és így kevesebb lehetőségem van hibázni.

Ne add fel! Mivel fogom lefordítani egy-egy ámokfutásomat? :)

Amúgy néhány 3 éve PIC 16F1936-nak nem ismerte minden utasítását, így írtam hozzá makrókat, amelyet include-oltam a forrásba. Meg egy előfeldolgozó scriptet, amely csinált egy olyan forrást, amelyben a makróim értelmet nyernek. :)

Ahogy elnézem, ezek hiányoztak:

movlb
movlp
bra
brw
callw
reset
addwfc
asrf
lslf
lsrf
subwfb
addfsr
moviw
movwi

Ezek már belekerültek a kódkészletbe?

tr '[:lower:]' '[:upper:]' <<<locsemege
LOCSEMEGE

Tudod, mit árulj el nekem? Van egy PICKit 2 nevű programozóm, forrásból lefordítottam a pk2cmd-t. Ez eddig jó. Viszont a PK2DeviceFile.dat nem ismeri például a PIC16F1704-et. Erre a problémára van ötleted?

Szerk.:

Executable Version:    1.20.00
Device File Version:   1.55.00

tr '[:lower:]' '[:upper:]' <<<locsemege
LOCSEMEGE

A PICKit 2 egy régi eszköz amit pár éve már nem támogatnak, azaz nem adnak ki hozzá új firmware-t és az ehhez illeszkedő PC oldali kezelőprogramot. Esetleg lehetne bűvészkedni a PK2DeviceFile.dat-ban például ezzel az XP-re készült programmal. (Van róla egy fórum-szál itt.) Ehhez azonban ismerni kell a beírandó adatokat. Ezen kívül adódik még egy probléma: A Microchip az újabb MCU családok esetében időnként változtat a felprogramozás protokollján. Mivel az említett PIC16F1704 MCU a fejlettebb PIC14E családba tartozik (ami csak pár éves) az öreg PICKit 2 esetében kevés esély van rá hogy be tudná tölteni a programkódot.

Ha van kedved vesződni az egésszel akkor a Microchip féle MCU-khoz ezen a lapon találsz információt a programozás módjáról. Ha konkrétan a PIC16F1704 érdekel akkor ez az adatlap kell neked.

---------------------------------------------------------

Hamarjában kerestem még pár segédprogramot, vagy a forrásukat a PK2DeviceFile.dat buherálásához:

Linux-hoz:

pk2-piculear-conversion-tools
pk2dft.c

Ez utóbbiról egy fórum téma.

---------------------------------------------------------

XP-hez:

Ezen a honlapon a szerkesztő programon kívül találsz egy módosított PK2DeviceFile.dat-ot is:
http://jared.geek.nz/2013/aug/pickit2-revisited

---------------------------------------------------------

Van egy másik módosított PK2DeviceFile.dat, de tudnod kell hogy ez a PICKit 3-hoz készült. Nem tudom hogy ez jó lehet-e. A PICKit 2 esetleg agyonvághatja vele az MCU-t.

Köszönöm a segítséget! PIC-et szerencsére nem túl bonyolult programozni, a dokumentációk nyíltak, elérhetők.

Anélkül, hogy konkrétan utána néztem volna, úgy gondolom, a PICKit 2 hardware-e alkalmas az új eszközök programozására is. Az ICSPCLK, ICSPDAT - ez persze kétirányú -, -MCLR, VDD vonalakat kell meghajtani, ezt a PICKit 2 tudja. Egyedül akkor van gond, ha a -MCLR valami egzotikus feszültséget igényelne.

Van néhány lehetőségem:

- használom a PICKit 2-t és általa támogatott PIC-kel tervezek. Hátránya a konkrét példában, hogy külön tokba kell műveleti erősítő, míg lenne olyan PIC, amelyben van, így elegánsan, egy tokból felépíthető lenne a célhardware

- korszerűbb fejlesztői környezetet vásárolok, hátránya, hogy ez kiadás

- módosítok a PICKit 2 firmware-én, valamint a PC oldali programon, vagy újraírom azt, itt külön probléma, hogyan töltöm le a PICKit 2-nek az új firmware-t

- építek saját programozót, megírom a PC-s, és a programozó oldalát, bele kell ássam magam az USB szépségeibe, de a linuxos udev-et sem tudom megkerülni akkor, valahogy erre sem vágyom

- semmit sem csinálok PIC-kel, leülök egy csendes sarokba, s megvárom, míg elmúlik az élet

Momentán egyik változat sem ideális, majd meglátom, merre tovább. :)

tr '[:lower:]' '[:upper:]' <<<locsemege
LOCSEMEGE

"...úgy gondolom, a PICKit 2 hardware-e alkalmas az új eszközök programozására is."

Fizikailag igen, amennyiben képes pl. 3,3 V-os tápot is kiadni, de szerintem a benne lévő firmware csak a régebbi protokollokat tudja. Az újabbak esetében lehetnek olyan eltérések, mint pl.: Egy beírásra váró blokk cél-címét kettővel több biten kell átadni az MCU-nak, vagy valahol más várakozási időt kell beiktatni. Sok paramétert a leíró adatbázis határoz meg, de lehet hogy nem mindet. Ezek pedig valószínűleg "bele vannak drótozva" a PICKit 2 firmware-be.

megjobb ha a pickit2-re csinalsz egy open firmware-t;) Sot, ha jol emlekszem egyebkent a firmware public, szoval lehet haxolni. Egyebkent sejtesem szerint a hardware lesz a ludas a dologban, az uj szerias piceknel az MCLR 10-14 volt kozott van es kell a flash ujrairasahoz, ezt meg a pickit2 nem tudja

// Happy debugging, suckers
#define true (rand() > 10)

Hát nem is tudom. Én annak idején ezzel próbálkoztam: http://usbpicprog.org/

Módosítottam az eredeti készüléken, mivel a FET-ek miatt gyalázatosan sokat esett a kimenő +5V-os táp. Csak bipoláris tranzisztorokkal lett jó. Legalább 1A-es Schottky diódát kellett beleraknom hogy azon is kis feszültség vesszen el. (Itt a könyökponti feszültség kis áramnál lejjebb van.) Aztán Z-diódákkal és jumperekkel megoldottam azt is hogy legyen 3,3 V-os kimenő táp is. Ezután pedig belenyúltam a firmware forrásába mivel nekem kellett a PIC18F46K22, amit akkoriban nem ismert. No persze a PC-s vezérlőprogramba is bele kellett írnom. Ráadásul a wxWidgets fejlesztői változata kellett hozzá amit a gépem jól leizzadva majdnem egy órán át fordított.

A PIC18F46K22-re írtam egy olyan firmware-t amivel a "Magyarok a Marson" című robot versenyre segítettem be a szervező srácnak. Ezt valamivel be kellett égetni az MCU-ba. Már van pár éve.

Kezdek belenyúlkálni a forráskódba is. Pár napja kibővítettem a figyelmeztető és hibaüzeneteket (gpasm, gplink), ezen kívül javítottam pár kisebb hibát. Állandóan tesztelem a változtatásaimat, eddig még semmi sem lett rosszabb. :-)

A gpdasm program egy új parancssori kapcsoló hatására a visszafejtett kódban egyes regiszterek címe helyett azok nevét mutatja. Ezek a regiszterek az adott MCU család (PIC12, PIC12E, PIC14, PIC14E, PIC16, PIC16E) minden tagjában ugyanazon a címen léteznek és bankváltás nélkül el lehet érni őket. Ezen kívül a program már nem fogja visszafejteni a CONFIG szakaszt, mivel az nem utasításokat tartalmaz. (Gondolkozom azon hogy e képeségét kiterjesztem az IDLOC szakaszra is.)

----------------------------------

Megtettem. Nem erőlködik az IDLOC és az EEPROM területekkel sem.

Csináltam egy olyan fejlesztést amivel a kiírás előtt egy külön menetben igyekszik felismerni a kódban a címkéket. Értem ezalatt az ugró és a szubrutinhívó utasítások cél címeit. Ezeknek nevet ad és a visszafejtett forráskódban már így hivatkozik rájuk. A felismerés nem tökéletes akkor ha beágyazott adatokkal próbál szkanderezni és akkor sem ha nem lehet biztosan megmondani hogy az elágazó utasítás melyik program-memória lapra fog továbblépni. (Ehhez szimulátorban kéne futtatni a kódot.) Ismeretlen kódok viszafejtésében már ez is segítség.

A gpasm mostantól kezdve egy parancssori kapcsoló hatására készít egy .err állományt is. Ebben összegyűjtve megvan minden hibajelzés, figyelmeztetés és üzenet. Ez nagyon hasonló ahhoz amit az mpasmx készít. Gyakorlatilag annyi a különbség hogy a gpasm több esetben bővebb információt ad.

Már elég sok változás összejött és ma kiadtam a gputils-1.4.0_RC1-et. Néhány újítás:

-- Bővítettem a hibaüzeneteket. (Néha elegem volt abból hogy egyik-másik üzenet csak homályosan utalt a hibára.)
-- A gpasm CONFIG direktíváját - a PIC17 kivételével - kiterjesztettem az összes PIC eszközre. (Eddig ez csak a PIC18F sorozathoz létezett. Az mpasmx továbbra is csak ezt tudja.)
-- A gpasm a PIC18F eszközökre ismeri az IDLOCS direktívát. (Más a megvalósítás mint az __idlocs esetében. Itt már stringet is meg lehet adni, akár több darabban is.)
-- A gpasm - belső táblázatok segítségével - képes listázni a processzorok képességeit, lehetőségeit. (Memória méretek, a config bitek nevei és a hozzájuk tartozó értékek, stb.)
-- A gpasm a választott processzortól függően ismer több előre definiált állandót. (__EEPROM_START, stb.)
-- A gpdasm a megfelelő parancssori kapcsolók hatására a visszafejtett forráskódba írja az SFR-ek és azok bitjeinek nevét, valamint - lehetőség szerint - megnevezi a címkéket. Szöveges formában megjeleníti a CONFIG direktívákat és ahol lehet az IDLOCS tartalmát. Mindehhez segítséget ad az hogy lehetséges egy listafájlban megadni a címkék neveit. Az így készített forráskódot általában azonnal le lehet fordítani a gpasm segítségével.

Bővebb információkat itt lehet olvasni.

gputils-1.4.0_RC1.tar.gz
gputils-1.4.0_RC1.exe

Mostanában jutott rá több időm és a teendők listáján szerepelők közül megvalósítottam két komolyabb dolgot. A gplink mostantól képes arra hogy kidobja a fölöslegessé vált Pagesel és Banksel direktívákat. Egészen pontosan a hatásukra keletkezett utasításokat. Ettől kisebb lesz a lefoglalt kódterület és valamennyit gyorsít a programok futásán is. A megoldás jól működik a tesztjeim alatt, de ez még kevés. Nagy számú próbára van szükség olyan helyzetekben amiket csak a valós élet képes produkálni, ezért a megvalósítás jelenleg kisérleti állapotban van.

A legújabb, javított csomagok:

gputils-src-20160626-1223.tar.bz2
gputils-20160626-1223-setup.exe

Ez azt is jelentheti, hogy a 302 üzenet nem lesz annyiszor feleslegesen kiírva?

Van egy másik speciális problémám. Pl. a pic18f24k50 esetén néhány regiszter (a 0f60 alattiak) csak a bsr-en keresztül érhetől el, mert nem fértek bele az access tartományba. Ez nem a bank0 eset, mint a 302-es warning. Ezt a P18F24K50.INC módosításával oldottam meg, pl.: ANSELA -> ANSELAb. Ebből látom, hogy ez a regiszter csak a megfelelő értékű bsr segítségével címezhető. Ilyen esetben az ANSELA=0f5b címéből következik a bsr megfelelő értéke is, tehát az ellenőrzés elvégezhető lenne, vagy a 302-től eltérő (új) hibaüzenet kerülhetne mellé.

Természetesen kipróbálom.

"Ez azt is jelentheti, hogy a 302 üzenet nem lesz annyiszor feleslegesen kiírva?"

Ezek számát abszolút módban redukálja az hogy a gpasm többnyire már követni tudja a bank- és lapváltásokat. Ezekre van is néhány beépített változó amiket használhatsz a makróidban. Ez nem működik akkor ha object kódot fordítasz.

"Ilyen esetben az ANSELA=0f5b címéből következik a bsr megfelelő értéke is, tehát az ellenőrzés elvégezhető lenne, vagy a 302-től eltérő (új) hibaüzenet kerülhetne mellé."

Ez nehezebb ügy mivel el kell dönteni hogy egy SFR-ről van szó vagy csak egy GPR a ludas.

Egyébként éppen most tettem közzé egy olyan változatot amiben a gplink -O2 módban képes kidobni azokat a halott részeket is ahol két eljárás két külön kódszakaszból egymást hívja, de semmi más nem használja őket.

-----------------------------------------
szerk.

Akkor sem reklamál ha a szájába rágod hogy te pontosan tudod mit csinálsz. Vagyis ehelyett:


    banksel ANSELA
    movwf   ANSELA

Ezt írod:


    banksel ANSELA
    movwf   ANSELA, B

Ha megadod a Access bit értékét akkor a gpasm nem próbálja meg kitalálni hogy mit is szeretnél, hanem elfogadja azt amire utasítod.

Köszi a kiegészítést!
Kizárólag abszolút módot használok, ezért különösen érdekel a módosítás.
A helyzet elég speciális, mert még a banksel-t is kispórolom. A 2k ram két bankját - ebből egyik az access - használom közvetlenül. Ezért nincs default, mindig odaírom az A/B címzést. Így futottam bele ebbe a hibába, amikor mindezekben nem volt benn néhány SFR.

Ha lesz időm, kipróbálom azt a kontrollert is, ahol az SFR-ek - legnagyobb örömömre - 32 bankban helyezkednek el.

Az előző hozzászólásod hatására okosítottam egy kicsit az ide vonatkozó figyelmeztető üzeneteken. Azonban ezeket még csak az object módban próbáltam ki. (Az abszolút mód nekem valamiért olyan elmaradottnak tűnik és rendszerint elfeledkezem róla.) Amikor ráérek akkor majd abban is tesztelek és ha jó akkor megy a következő commit és utána csinálok csomagokat is.

"Ha lesz időm, kipróbálom azt a kontrollert is, ahol az SFR-ek - legnagyobb örömömre - 32 bankban helyezkednek el."
Le vagy maradva. :-) Nézd meg ezt, mert néhány legújabb társához hasonlóan 64 RAM bank van benne. (Persze nem mindben vannak SFR-ek.)
PIC16F19197 SFR map
Egyelőre csak ennyi infó van róla mert amikor legutóbb néztem akkor még nem volt róla adatlap.

Az abszolút mód mindjárt érthetővé válik, ha a kód tartalmaz:
- usb drivert
- aes256-cbc - ahol néhány ram lapra átmásolok táblázatokat, hogy gyorsabban menjen
- műszerről lévén szó 30ks/s (2B adatok) mérő buffer
- elég sok változó
- néhány szorzás-osztás interrup alatt
- néhány ugrótábla
- azonosítók a szerkezet hitelesítéséhez
A ramot ugyan nem kell cipőkanállal rendezni, de zoknit már nem merek ráhúzni. ;)
A flash meg pontosan be van rendezve a másolásvédelmi opciók miatt.
Ezt meg lehet írni akár C-ben is, de ott valószínűleg többet kell magyarázni mi hova kerüljön.
Így az abszolút mód bonyolultabbnak tűnik, de rögtön látom a listából, hogy lineárisan minden a helyére került.
Ha esetleg másik cpu-ra kell rakni, akkor sincs túl sok munka vele.

A következő játék egy kisebb hőmérő webes configgal. A flash 16kB, a ram 512B, a logót már összenyomtam 5k-ra. Talán nem is tudom mire vállalkoztam. :)

Ez a PIC16F19197 már tényleg nem gyerekeknek való. ;) Sajnálom a processzort a sok banksel miatt, ezért elhatároztam, hogy a PIC18 fejlettebb verzióinál kisebbet nem fogok használni. És mint írtam is, az access + 1 bank minden (általam végzett) feladathoz elegendő. No, meg a kisebb sorozatú termékekben az ár sem közömbös. Ennek megfelel a PIC18F24K50 (ha kell usb), és a PIC18F14K22.
De!
Itt csücsül a fiókban egy-egy PIC24FJ128GA204 és PIC24FJ128GB204! Jobb híján az ASM30 lesz az első tool. :( Aztán meglátom, hátha sikerül makróznom a gpasm-hez. A másik megoldás lehet a naken_asm.

A PIC18 szériában nagyon elcsendesedtek a dolgok, pedig azt vártam hogy ez indul fejlődésnek, a PIC16 és társai pedig szépen kimúlnak. Ehhez képest egyre másra jelennek meg a fejlettebb PIC16-ok. Aztán hosszú idő után nemrég érkezett a PIC18F27K40 támogatás az Mplabx-be, de még nincs adatlap sem róla. Egyelőre csak annyi érdekesség tűnt fel hogy az EEPROM a 0x310000-0x3103FF címtartományban van és a config bitek magyarázatai között szó esik valamilyen Scanner modulról, jelentsen ez bármit is.

"Itt csücsül a fiókban egy-egy PIC24FJ128GA204 és PIC24FJ128GB204!"

Tudom, ezeket nem támogatja a gputils. Úgy látom hogy ehhez sajnos egy másik gputils-t kellene írni, a fordítótól kezdve a linkeren át a segédprogramokig. Teljesen más az utasításkészlet és amikor belegondoltam azt sem tudtam eldönteni hogy milyen utasítás szintaktikát lenne érdemes követni: Tákolgatni a mostanit és kockáztatni hogy elromlik az ami eddig működött, vagy átvenni az asm30 nyelvi elemeit, ami egy újabb fordítót jelent. Röviden fogalmazva, úgy érzem hogy ez nekem egyedül túl nagy falat lenne, segítségem meg nincs. Visszajelzéseket ritkán kapok, mintha nem is használná senki a gputils csomagot. Néha olyan érzésem van mintha valahol a hátsó udvaron farigcsálnék egy darab fát és az ugató kutyát sem érdekelné hogy mit csinálok. (Persze lehet hogy ha valamit elbarmolnék akkor lenne tiltakozás.)

Ezzel még nem találkoztam: naken_asm

A PIC18 szériában nagyon elcsendesedtek a dolgok...
Ebben semmi csoda nincsen.
Még amikor éppen csak megjelent az Intel 386, én éppen 8085-ön dolgoztam. Ha nem a keleti blokkban vagyok, kacsintgattam volna a 8051 (bár a kollégák használták szovjet olajkitermelő rendszerek felügyeletére kifejlesztett beredezésekben), vagy a 7011 felé. Ezeknek az egyedi ára 5-10$ körül mozgott. Ugyanakkor a világon legnagyobb példányszámban eladott CPU vezérlésre kifejlesztett 4 bites típus volt 0,3-0,5$ áron.
A PIC16 fejlődése hasonló. Miközben az általam fejlesztett termékek legfeljebb néhány száz példányban készülnek, a gyártó 10kunit egységre adja meg az árat. Ez nem csak a "nagykernek" szól, hanem olyan gyártóknak, akik tényleg nagy sorozatban készítenek az ipari vezérléstől a kütyükig mindenfélét. A PIC16 belseje valószínűleg egyszerűbb, könnyebb ellátni újabb funkciókkal. Ha a futásidő nem kritikus, a fejlesztés C/C++ alapokon megy, akkor senkit nem zavar a 64 bank.
A PIC18 kihalásának oka ugyanez. Ha nagyobb teljesítményre van szükséged, akkor árban ugyanott van egy sokkal jobb tulajdonságokkal rendelkező PIC24. Becslésem szerint a PIC18->PIC24 váltással a futásidő 60-90%-kal, a kód mérete 60-80%-kal csökkenhet. Persze ez csak akkor igaz, ha nem használod az ide nem illő C függvényhívási konvenciókat. Egy egyszerű példa a két szerkezet közti eltérésre. A soros port 8/9 bites kezelése egyszerűsödött, a hw handshaking beépített, és a tetejére rápottyantottak egy IRDA kezelőt. Ha ilyen dolgokat használtál, akkor a szoftver több mint fele feleslegessé válik, és még nem is említettem a DMA-t. A microchip lelkendezett a PIC16 és PIC18-ba beépített Aztive Clock Tuning modul miatt. (PIC18F2550->PIC18F24K50 vagy 12 év az eltérés!!) Későbbi modellekben már nem így hívják, de mindegyikben benne van. Ez aváltás a termék kialakításakor 1200->600Ft csökkenést jelent. Ez nálam két esetban az összes alkarész árának az 50-80%-a!
Még egy érdekesség: Az amatőrök nagyon ritkán lépnek feljebb, ezért veszik a PIC18F2550, PIC16F628 és társait, mert ezzal van tele a net. No, meg a kínai ebay. ;)

A Scanner modul tényleg akármi lehet. :)

fordítótól kezdve a linkeren át ...
Naugye! Az abszolúthoz nem kell linker. :)

átvenni az asm30 nyelvi elemeit...
Tudom, már régen deklaráltad, hogy nincs időd.
Ezért is kerestem rá mégegyszer valami fordítóra, szóval a naken_asm nekem is vadiúj. Sajnos a néhány oldalas "dokumentáció" (a README vége:)) alapján már fenntartásaim vannak. Nincsen benne radix! Mivel az MPLAB IDE-t használom, - főként a build, flash, reset gombokat - kellene hozzá egy preprocesszor, meg illesztés. Vagy visszatérek a makefile-technológiához.
Az asm30-at sem próbáltam még, remélem éppen olyan silány mint a többi! :(
Az utasítások talán nem annyira eltérőek, csak a sokféle címzési mód az újdonság. Emiatt biztosan szükséges lesz egy switch a 8 és 16 bit közé, vagy tényleg új fordító. Bár nem értek ehhez a tudományhoz, de a naken_asm-ben elég jól le vannak írva a tokenek.

Hááát, ahogy nézem, legalább 2-3000 felhasználó lehet! Abból indulok ki, hogy én is ritkan frissítek, ha működik. Talán csak az öreg emberek használják, akik még szeretnek pontosan programozni. Vagy annyira jól működik, hogy nincs szükség visszajelzésre. Tudom, az alkotónak ez a legrosszabb. Hidd el, ezzel nem vagy egyedül!

Ennek a szép hosszú szösszenetnek az örömére ide teszem a legfrissebb linkeket:

gputils-src-20160630-1227.tar.bz2
gputils-20160630-1227-setup.exe

Néhány üzenetben több információ van, így könnyebb javítani a hibákat. Javasolom hogy próbáld ki. Kíváncsi vagyok hogy mit szólsz hozzá, különös tekintettel az ANSELA regiszer körüli gondjaidra. :-)

Nincs közöm a Fedora repókhoz. Az index : rpms/gputils.git oldal szerint Roy Rankin foglalkozik ezzel. Jó sokáig csak a gputils-1.3.0 volt bent. Most néztem hogy betette a legutóbbi stabilnak "kikiáltott" változatot. Fejlesztői csomagokat meg nem szokott berakni, legalábbis nem láttam ilyet. Magamnak már régóta csinálok rpm csomagokat.

Rossz híreim vannak!

1)
bsr=4, de Access helyett a bsr alapján jön az üzenet

00058C 0104           01082             movlb       4                       ;switch to USB RAM
Message[302]: Register in operand not located in RAM Bank 4. Ensure that Bank bits are correct: 'ADCON0' (Addr: 0x0FC2; Bank_15: 0x0F00; Offs: 0x00C2)
00058E 80C2           01083             bsf         ADCON0, ADON, a

2)
bsr=4 alapján nem jó az üzenet

A BD3STAT deklarációja a 4. bankon van, kiragadva a listából (az inc-ben nincs deklarálva félig-meddig érthető okból, de ez egy SFR - az USB endpoint része - itt meg "csak egy változó". ):

0000040C            00024         BD3STAT
...
Message[302]: Register in operand not located in RAM Bank 15. Ensure that Bank bits are correct: '_BD3STAT' (Addr: 0x040C; Bank_4: 0x0400; Offs: 0x000C)
0009AC AF0C           00007             btfss       BD3STAT, UOWN, b

3)
Ugyanez előfordul akkor is, ha Access-re hivatkozok.

Message[302]: Register in operand not located in RAM Bank 15. Ensure that Bank bits are correct: 'O_PeriodTimestampL' (Addr: 0x0020; Bank_0: 0x0000; Offs: 0x0020)
001F06 6E20           02103             movwf       O_PeriodTimestampL, a

4)
Úgy látom az ANSELA, a helyett ravasz módon ANSELA, b kódot fodítasz.
És ide passzol a Bank 15-ös üzenet! :)
Tehát a bsr=4 és bsr=0f eseteket jól kezeled.

A program felépítése

Blokk1


			org		0
			movlb		0f	;switch to unmapped SFR region
			goto		Start

Blokk2


HpInterrupt
LpInterrupt
Subroutines1

Blokk3


Start                  (unmapped SFR init)
			movlb		4	;switch to USB RAM
                       (init)
MainLoop
Subroutines2

Az összes direkt címzésű változó az Access területen és a 4. bankban van. Inicializálás után a bsr nem változik.
A teszt érdekében a bsr-t a Blokk1-ben 4, a Blokk3 elején 0f, majd az inicializálás után 4 értékre állítottam. Az üzenetek nem változtak. (Vagy csak nem, vettem észre.)
Ami kifogástalan az az ANSELA hiba kezelése.

A 302 üzenetek 1200->1032 darabra csökkentek.
A fodított bináris megegyezik.
(PIC18F24K50)

Ezen még rugóznom kell egy ideig. Most éppen a memóriakezelést fejlesztem. A mindenféle láncolt listák kezelését igyekszem külön választani magunknak az adatoknak a kezelésétől. Ez előtt az object kódok beolvasásakor a gpreadobj.c egy érdekes megoldás használt: Pl. a szimbólumok kezelésekor egy tömbben foglalta le az összes szimbólum leíróját amiket a későbbiekben a többi könyvtári modul láncolt listaként kezelt. Láttam olyat is hogy ehhez az egy tömbben lefoglalt bagázshoz később valamelyik modul hozzátett olyat szimbólumot amit - ahogy illene - önállóan foglalt le és illesztett a lánc végére. Ezért aztán a linker a munkája végén sohasem szabadította fel a memóriát, mivel azt a teljes lánc elemein végigfutva kellett volna megtenni, amiből persze balhé lett volna. Ezt már rendbe raktam akkor amikor megcsináltam a pagesel és banksel optimalizációt. Ha ezzel megvagyok akkor újra megnézem a hibaüzeneteket.

Légy szíves nézd meg hogy a kódodban az említett példaüzenetek előtt az utolsó Banksel direktíva melyik bankot választotta ki. Abszolút módban a gpasm igyekszik követni a bank kijelöléseket és azok alapján állítja elő a figyelmeztető üzeneteket. Egyszerűen meggyőződhetsz erről ha a kódba beteszed a következő sort:


    messg "__ACTIVE_BANK_ADDR: #v(__ACTIVE_BANK_ADDR)"

Ez valami hasonló kiírást ad:


main.asm:36:Message[301] MESSAGE: "__ACTIVE_BANK_ADDR: 256"

Annyi hátránya van hogy nincs formázási lehetőség és emiatt decimális számmal ír ki mindent.

Aha. Látom, a -1 esetén biztosan érvénytelen a bank address, de 15-ként jelenik meg.
Az "Addr:" érték mindenhol jó, csak az Access-t figyelembe kéne venni.
Tehát,
ha access
-> lehet-e a SFR-t címezni vele
-> vagy acces területen van a GPR
ha nem
-> érvényes-e az __ACTIVE_BANK_ADDR
--> egyezik-e a címmel

1)

00058E 0104           01085             movlb       4                       ;switch to USB RAM
Message[301]: MESSAGE: "__ACTIVE_BANK_ADDR: 1024"
                      01086 1024
Message[302]: Register in operand not located in RAM Bank 4. Ensure that Bank bits are correct: 'ADCON0' (Addr: 0x0FC2; Bank_15: 0x0F00; Offs: 0x00C2)
000590 80C2           01087             bsf         ADCON0, ADON, a

2)

Message[301]: MESSAGE: "__ACTIVE_BANK_ADDR: -1"
                      00007 -1
Message[302]: Register in operand not located in RAM Bank 15. Ensure that Bank bits are correct: '_BD3STAT' (Addr: 0x040C; Bank_4: 0x0400; Offs: 0x000C)
0009AE AF0C           00008             btfss       _BD3STAT, UOWN, b

3)

Message[301]: MESSAGE: "__ACTIVE_BANK_ADDR: -1"
                      02105 -1
Message[302]: Register in operand not located in RAM Bank 15. Ensure that Bank bits are correct: 'O_PeriodTimestampL' (Addr: 0x0020; Bank_0: 0x0000; Offs: 0x0020)
001F06 6E20           02106             movwf       O_PeriodTimestampL, a

4)
Sajnos ez sem jó.
Itt kétszer rontom el:
- a bsr=4 nem jó
- az ANSELA access címzése sem jó

0004FC 0104           00935     movlb       4
0004FE 0E0F           00936             movlw       0f
Message[301]: MESSAGE: "__ACTIVE_BANK_ADDR: 1024"
                      00937 1024
Message[302]: Register in operand not located in RAM Bank 4. Ensure that Bank bits are correct: 'ANSELAb' (Addr: 0x0F5B; Bank_15: 0x0F00; Offs: 0x005B)
000500 6E5B           00938             movwf       ANSELAb, a

A gpasm a bank kezeléssel kapcsolatos figyelmeztető üzeneteket egy utasítás csoporton belül is több helyen állította elő. Ennek véget vetettem. Közben rájöttem hogy object módban is érdemes követni a bankváltásokat akkor ha a regiszterek címe fordítási időben is megvan. Tehát készítettem egy újabb változatot amit érdemes lenne kipróbálnod:

gputils-src-20160705-1229.tar.bz2
gputils-20160705-1229-setup.exe

A 302 üzenetek 1200->237 darabra csökkentek.

Az ANSELA jelenség - lényeg a commentben:

Message[1302]: RAM Bank undefined in this chunk of code. Ensure that bank bits are correct. Assuming bank 15 from now on.
...
0004FC 0104           00935     movlb       4
0004FE 0E0F           00936             movlw       0f
Message[301]: MESSAGE: "__ACTIVE_BANK_ADDR: 1024"   ;4 = Ok
                      00937 1024
Message[301]: MESSAGE: "ANSELA ADDRESS: 3931"       ;0f5b
                      00938 3931
000500 6E5B           00939             movwf       ANSELAb, a              ;Hiba: Access
000502 6F5B           00940             movwf       ANSELAb, b              ;Hiba: bsr=4

Valójában az üzenettel megadtad a választ!
Hiányzik az assume direktíva.
(Ezért írogattam, hogy meg kellene nézned néhány "nem C like" asm fordítót.)
Az assume az x86 assemblerek sajátja, és független az abs vagy obj módtól. Pl. itt a 8.8.10 fejezet.

Ezeket az üzeneteket ("Assuming...) az ember nem akarja látni, ezért is szűri ki. Még ez a 237db is olyan sok, hogy inkább szeretném látni mondjuk az 5 hibát helyette!

A programra, amit feljebb vázoltam elég lenne ennyi:
Blokk1

			org		0
			movlb		0f	;switch to unmapped SFR region
			goto		Start

Blokk2

assume   Banksel:Bank4
HpInterrupt
LpInterrupt
Subroutines1

Blokk3
[code]assume   Banksel:Bank0f
Start                  (unmapped SFR init)
			movlb		4	;switch to USB RAM
assume    Banksel:Bank4
                       (init)
MainLoop
Subroutines2

Ugyanez obj módban is használható. Pl. az USB driver esetén elegendő egyszer megadni a Bank4-et.
Üzenetre meg csak akkor van szükság, ha tényleg hiba van. Ehhez viszont figyelni kell az access-t.

Nem lehet, hogy a -1 étéket még mindig 0f-ként értelmezed?

Annyit már módosítottam a gpasm-on hogy ne nyafogjon addig amíg csak az Access RAM-ot használod és a regiszter valóban ott is található.

Ezt az assume direktívát először nem is tudtam hová tenni. Aztán a linkelt odalt nézve felrémlett a számítógép programozással való ismerkedésem első időszaka. (Kölcsön kapott 286-os alaplap, Herkules kártya, 5.25 floppy meghajtó. A monitor egy a Videoton-tól kiárusított hullámpapír csomagolású 30 cm-es átlójú monokróm képcső, amivel együtt volt a vezérlő panel, így működött a csomagolásában hagyva is.) Csak a masm-hoz tudtam hozzájutni. Ha délelőttös műszakban voltam akkor este és éjszaka, ha délutános voltam akkor délelőtt nyúztam a gépet. (Ez valamikor 1990 környékén volt.) Assembly-ben programozva pár év alatt eljutottam odáig hogy írtam egy egyszerű assemblert i8048 MCU-ra. (Az indított erre hogy láttam egy Turbo Pascal-ban készített assemblert ami iszonyú lassan dolgozott.) A program írása közben is sokszor használtam az assume direktívát. Itt azonban nem sok hasznát vennénk. Nincs szegmens regiszter, hacsak nem csúfoljuk annak a bank kiválasztó biteket vagy a BSR regisztert (már ahol van). Direktíva viszont van, a Banksel hasonló cél érdekében létezik mint az Assume. Legalábbis én így értelmezem.

Egyébként küldhetnél egy kis példa kódot ami pontosan szemlélteti a problémádat. Sokkal könnyebb konkrét kóddal tesztelni mint kitalálni valamit amiből lehet hogy éppen az a helyzet hiányzik amit te sérelmezel. :-)

Ez az első kijelentés pozitív!

Ezek szerint láttál már "valódi assembler fordítót is". A MASM nem 8048-ra fordít, hanem pc processzorra. A másik meg az ASM48 lehetett, de az Intel termék.
Bár 1983-tól a VIDEOTON Fejlesztési Intézetben dolgoztam, de komolyan mondom: Azt a monitort nem én adtam el! ;)

Nincs szegmens regiszter, ...
Hát dehogy nincs! Azért mert banknak hívják, a memória bájtot meg (memory)file register-nek attól még az.

Ez egy 8086-os kód
mov ax,@Data
mov ds,ax
assume ds:Data

Ugyanex PIC-re
movlw @Bank0
movwf BSR, a
assume BSR:Bank0

Az assume azt jeleni amit jelent: Tételezd fel, hogy a következő sortól kezdődő kódban a ds (data segment register)/bsr (bank select register) által végzett címzés a Data/Bank0 címkével jelzett memóriaterületre (szegmensre/bankra) vonatkozik! Minden olyan címzés, ami az előbbieknek megfelel azt tekintsd jónak, ami ettől eltér azt tekintsd hibának és jelezd! Nem írom le az összes x86 címzési módot ami megfelelő, de PIC esetén a ...,b vagy a default, ha elhagyod a b-t.

Az eltérés a következő:
BANKSEL
This directive generates bank selecting code...
Tehát ez a direktíva - ami inkább egy okos beépített makró - kódot generál (esetleg mégsem) a különböző felépitésű processzorok számára.
Hatása - ha figyeled - a kód blokk végéig terjed. Vagy a következő call-ig, de ez egy, másik téma.

ASSUME
...but you must also tell the assembler where and when that segment is a data ...segment. The assume directive provides this information to the assembler.
Tehát az assume nem generál kódot, csak a fordítót informálja, hogy mit higgyen a regiszter tartalmáról. A regiszter betöltéséhez meg kell írnod a kódot, mint a fenti példában. De a regiszter betöltéséhez semmi köze se oda, se vissza.

Példa:

#include <P18F24K50.INC>
        list n=0, st=off
        cblock  400
        Bank4:0
        Bank4_data
        endc

        cblock  500
        Bank5:0
        Bank5_data
        endc

        org        0
        movlb      4
        call       Bank4DataManipulation
;       assume     BSR:NOTHING          ;a call miatt automatikusan
        call       Bank5DataManipulation
stop
        bra        stop

Bank4DataManipulation
;       assume     BSR:Bank5            ;helyesen: high Bank4, de ezt a fordítónak kellene megoldani
;ezek az üzenet nem mond semmit, a nincs ASSUME
        movf       Bank4_data,w,b       ;ASSUME -> helyes
        movf       Bank5_data,w,b       ;ASSUME -> hibás
        movf       Bank4_data,w,a       ;high ADDRESS != BSR -> hibás
        return

Bank5DataManipulation
        movlb       5
;       assume      BSR:Bank5           ;helyesen: high Bank5, de ezt a fordítónak kellene megoldani
        movf        Bank5_data,w,b      ;ASSUME -> helyes
        movf        Bank4_data,w,b      ;ASSUME -> hibás
        movf        Bank4_data,w,a      ;high ADDRESS != BSR -> hibás
        return

        end

A BANKSEL felülírhatja az assume által megadott értéket.
Mondhatnád, hogy legyen a banksel az assume, mert ha nem kell, akkor nem generál kódot. Ennek ellenére eléggé ovashatatlanná teheti a forrást. Meg nem feltétlenül kell kényelmi szempontokból állandóan banksel-ezni.

Mindenesetre ez a módszer sokkal kifinomultabb, mint a fordítottja, amikor kiírod mit hisz a fordító. Van az az ugrótábla, amiről még én sem tudom mit is csinál, pedig én írtam. ;) Egy fordítótól - ami nem szimulátor - meg nem várható el a kód ilyen fokú elemzése.

Megint jó kérdés a call. Hasonló (csak egy kicsit és pongyolán) C-ben a

#pragma isolated_call function

Ez azt jelenti, hogy a function nem változtatja meg a változók értékét, tehát nem kell automatikusan menteni a függvényhívás előtt.
Tehát eldöntendő vagy egy direktívával szabályozni kell, hogy globális vagy kód blokk hatókörű az assume.

A MASM nem 8048-ra fordít, hanem pc processzorra.
Ezzel tisztában vagyok csak úgy látszik hogy tegnap este agyilag kissé zokni voltam. Azt akartam elővezetni hogy a PC-re csak assembly fordítót tudtam szerezni egy ismerőstől, C fordítóról nem is álmodtam. (Akkoriban nem is volt más lehetőségem.) Ez az assembly fordító a masm volt. Ennek segítségével fejlesztettem azt a programot ami végül le tudott fordítani egy assembly nyelvű forráskódot az i8048 MCU-ra. Egyszerű definíciókkal elboldogult de a makrózást meg sem kiséreltem mert olyan kacifántos lett volna amit nem tudtam átlátni és kezelni. (Nem volt semmi segítségem, mindent nekem kellett kitalálnom. Ha Pesten jártam akkor a Liszt Ferenc téren egy boltban tudtam szakkönyvekhez jutni.) Dióhéjban ennyi. :-)

Az említett zokni állapotnak köszönhető hogy összemostam a Banksel és az Assume szerepét és használatát. Te szépen leírtad a lényeget.

Nincs szegmens regiszter, ...
Hát dehogy nincs! Azért mert banknak hívják, a memória bájtot meg (memory)file register-nek attól még az.

Ezen az alapon a 12 és 14 bites MCU-kban van még egy virtuális szegmens regiszter a PCLATH felső bitjein. Vagyis mondhatnánk azt hogy a RAM-hoz van egy "Adat Szegmens Regiszter", a ROM-hoz meg egy "Program Szegmens Regiszter". (Utóbbi a 16 bites MCU-kban nincs mivel az egész ROM egyetlen lapon van.)

Lehet hogy vastag fejű vagyok de úgy látom ha az ember helyesen használja a Banksel direktívákat akkor az Assume szerintem pluszt nem hozna. Hiszen ha kiadom a Banksel-t és valóban csak az adott bankot használom (kivéve az Access területet) akkor a fordító csöndben marad mindaddig amíg ki nem címzek a bankból. Ekkor viszont az a dolga hogy figyelmeztessen.

Egyébként az __ACTIVE_BANK_ADDR és az __ACTIVE_PAGE_ADDR változó, tehát az értéküket te is átírhatod. Így csinálhatsz valami hasonlót mint az Assume. (Az érvénytelen értékek: __BANK_INV [-1], __PAGE_INV [-1]) Ezt a két változót és a többi állandót valamikor ez év január elején kezdtem beépíteni, amikor Petr Mikše beküldött egy patch-et: #65 Smarter message 302
Ezután vérszemet kaptam és belemásztam a dologba. Ennek nyomán valósítottam meg a bank követést, hasonló szemlélettel mint ahogyan a gpdasm-ban is csináltam.

Minden esetre javasolom az errorlevel direktíva használatával eltüntetni a zavaró üzeneteket. Éppen most bővítettem úgy hogy az errorlevel - gpasm módban - elfogad szám tartományokat is, például: errorlevel -302-310

gputils-src-20160706-1231.tar.bz2
gputils-20160706-1231-setup.exe

Hozzád képest szerencsés voltam.
Volt a munkahelyemen gép "* promptos rendszerrel", 2x160kB floppy.
Utána Enterprise 128, macro80, TurboPascal 3.0, pc kompatibilis floppy.
A végén xt, V20, (Az a NEC 8088, de magasabb az órajele, néhány utasítást mikroprogram helyett hardverrel csinál, van néhány spec. utasítása ÉS natív 8080 kódot is tud futtatni), amelyen futot az Intel Isis-II fejlesztőrendszer. Ez utóbbi fenn van a githubon! Ilyen rendszer azóta sem láttam. Van két modulod (és nem obj!), lefordítod, linkeled és lokálod, majd szimbolikus debugger. Mondjuk egy 10 modulból álló rendszerből megírhatsz 2 modult, és az előbbi módszerrel memóriában debuggolod. A végén a lokálás (jókimagyarfejezve: locate) az EPROM-ra történik és kész a firmware!
Amire saját pc-m kerekedett, addigra egy haver átrakta crossassemblerrel a m80+l80 csomagot pc-re.
Ja, és akkoriban 8085-re fejlesztettem.

Ezen az alapon a 12 és 14 bites MCU-kban van még egy virtuális szegmens regiszter...
Pontosan. Persze azért nem tökugyanaz, mint az x86 esetén, mert ott a szegmentálás "lefelé" a 64kB-os 8080 komptibilitást célozta (lást CP/M és .com formátum), felfelé meg a nagyobb, virtuális memóriát illetve a védett módot. Talán azért esik le nekem gyorsabban, mert (némi költői túlzással) csináltam már hardver támogatású multitaszkot, a hol a taszkcsere egyúttal a taszkhoz tartozó "adatszegmenst" is cserélte - éppúgy, mint egy 80286-on. (Ismétlem: némi túlzással.:))
Visszatérve a körmondat előtti gondolatra, nos ezek meg PIC-ek. A nagyon kicsik és az egyre nagyobbak között tán még a C sem biztosít teljes átjárást. Ahol már tényleg felejthető egy kicsit a hardver, az a szint a 24-eseknél kezdődik. Azért nem felejtem el, hogy a fordító készítőjének a teljes termékcsládra kell gondolni minden apró módosításkor. De bevallom, nekem már a fejlettebb PC18 a legkisebb szerkezet. ;)

Egyébként az __ACTIVE_BANK_ADDR és az __ACTIVE_PAGE_ADDR...csinálhatsz valami hasonlót mint az Assume.
Ez egy zseniális gondolat! Nem hiába az a hitvallásom, hogy a jó mérnök addig gondolkodik, amíg le tudja csökkenteni a munkaráfordítást. ;) Nem csak az assume, hanem mondjuk az assume_global is elkészíthető, ami passzol az "egy fix bankos" használati módomhoz. Már csak az a kérdés, hogy mennyire lineáris a fordító vizsgálata. De ez majd kiderül a végén.

ha az ember helyesen használja a Banksel direktívákat akkor az Assume szerintem pluszt nem hozna
Már csak az a kérdés, hogy az ember akarje-e használni a banksel direktívát? ;) Úgy lelki szempontokból, ha kódot generálhat, és a fordító nem biztos a bsr állásában... Az én esetemben tudom, hogy nem kell bankot váltani.

Az errolevel ki-be kapcsolgatva használható, de valószínűleg azért tűnt fel másnak is, mert sok felesleges üzenet keletkezett. (Tisztára gcc! :) Egyes esetekben a kapcsolgatást érdemes lehet ellenőrzés céljából blokkonként kapcsolgatni. Helyette kényelmesebb az assume. De most már megírom azokat a makrókat! (*)
A friss verzió már egész jól meghatározza a bsr értékét. Egyetlen -1 érték szerepel az üzenetekben a program eleje és a főprogram között, az interrupt-ban - ez jogos. A próbát mindig egy éles 5400 soros (lst,noexpand,sok makró) programon végzem.
Az üzenetek száma már csak 117, ami alig 10 százaléka az eredetinek.

Kipróbáltad a móricka tesztprogramomat, amit kértél? (Ott feljebb, be lehet keríteni egérrel! :) Mert abban semmi változás. :(

(*) Sajnos minél jobban el vagyok havazva, annál többet írok a fórumra. :(

Kipróbáltad a móricka tesztprogramomat, amit kértél?

Némi javítás után le lehetett fordítani:


	list n=0, st=off, p=18f24k50
	include <p18f24k50.inc>

    cblock	0x400
	Bank4:0
	Bank4_data
    endc

    cblock	0x500
	Bank5:0
	Bank5_data
    endc

    org	0
	movlb	4
	call	Bank4DataManipulation
;	assume	BSR:NOTHING		;a call miatt automatikusan
	call	Bank5DataManipulation
stop:
	bra	stop

Bank4DataManipulation:
	movlb	4
;	assume	BSR:Bank4		;helyesen: high Bank4, de ezt a fordítónak kellene megoldani
;ez az üzenet nem mond semmit, a nincs ASSUME
	movf	Bank4_data, w, b	;ASSUME -> helyes
	movf	Bank5_data, w, b	;ASSUME -> hibás
	movf	Bank4_data, w, a	;high ADDRESS != BSR -> hibás
	return

Bank5DataManipulation:
	movlb	5
;	assume	BSR:Bank5		;helyesen: high Bank5, de ezt a fordítónak kellene megoldani
	movf	Bank5_data, w, b	;ASSUME -> helyes
	movf	Bank4_data, w, b	;ASSUME -> hibás
	movf	Bank4_data, w, a	;high ADDRESS != BSR -> hibás
	return

	end

(Hiába van az "include <p18f24k50.inc>" sor a "&lsqb;code&rsqb;" jelzésű blokkban, csak az "include" látszik belőle. Ügyeskedni kell a &lt; -- '<' és a &gt; -- '>' jelzésekkel.)

Ez lett belőle:


gpasm-1.4.5 #1230 (Jul  7 2016)      main.asm   7-7-2016  15:13:57          PAGE  1


LOC    OBJECT CODE    LINE  SOURCE TEXT
  VALUE

                      00001 
                      00002         list n=0, st=off, p=18f24k50
                      00003         include <p18f24k50.inc>
                      00001         LIST
                      00002 
                      00003 ;==========================================================================
                      00004 ; Build date : Oct 21 2015
                      00005 ;  MPASM PIC18F24K50 processor include
                      00006 ; 
                      00007 ;  (c) Copyright 1999-2015 Microchip Technology, All rights reserved
                      00008 ;==========================================================================
                      00009 
                      02166         LIST
                      00004 
                      00005     cblock      0x400
  00000400            00006         Bank4:0
  00000400            00007         Bank4_data
                      00008     endc
                      00009 
                      00010     cblock      0x500
  00000500            00011         Bank5:0
  00000500            00012         Bank5_data
                      00013     endc
                      00014 
000000                00015     org 0
000000 0104           00016         movlb   4
000002 EC06 F000      00017         call    Bank4DataManipulation
                      00018 ;       assume  BSR:NOTHING             ;a call miatt automatikusan
000006 EC0B F000      00019         call    Bank5DataManipulation
00000A                00020 stop:
00000A D7FF           00021         bra     stop
                      00022 
00000C                00023 Bank4DataManipulation:
00000C 0104           00024         movlb   4
                      00025 ;       assume  BSR:Bank4               ;helyesen: high Bank4, de ezt a fordítónak kellene megoldani
                      00026 ;ez az üzenet nem mond semmit, a nincs ASSUME
00000E 5100           00027         movf    Bank4_data, w, b        ;ASSUME -> helyes
Message[302]: Register in operand not located in RAM Bank 4. Ensure that Bank bits are correct: 'Bank5_data' (Addr: 0x0500; Bank_5: 0x0500; Offs: 0x0000)
000010 5100           00028         movf    Bank5_data, w, b        ;ASSUME -> hibás
Warning[1204]: This register is not located on the Access RAM: 'Bank4_data' (Addr: 0x0400; Bank_4: 0x0400; Offs: 0x0000)
000012 5000           00029         movf    Bank4_data, w, a        ;high ADDRESS != BSR -> hibás
000014 0012           00030         return
                      00031 
000016                00032 Bank5DataManipulation:
000016 0105           00033         movlb   5
                      00034 ;       assume  BSR:Bank5               ;helyesen: high Bank5, de ezt a fordítónak kellene megoldani
000018 5100           00035         movf    Bank5_data, w, b        ;ASSUME -> helyes
Message[302]: Register in operand not located in RAM Bank 5. Ensure that Bank bits are correct: 'Bank4_data' (Addr: 0x0400; Bank_4: 0x0400; Offs: 0x0000)
00001A 5100           00036         movf    Bank4_data, w, b        ;ASSUME -> hibás
Message[302]: Register in operand not located in RAM Bank 5. Ensure that Bank bits are correct: 'Bank4_data' (Addr: 0x0400; Bank_4: 0x0400; Offs: 0x0000)
Warning[1204]: This register is not located on the Access RAM: 'Bank4_data' (Addr: 0x0400; Bank_4: 0x0400; Offs: 0x0000)
00001C 5000           00037         movf    Bank4_data, w, a        ;high ADDRESS != BSR -> hibás
00001E 0012           00038         return
                      00039 
                      00040         end


MEMORY USAGE MAP ('X' = Used,  '-' = Unused)

0000 : XXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXX ---------------- ----------------

All other memory blocks unused.

Program Memory Bytes Used:    32
Program Memory Bytes Free: 16352


Errors   :     0
Warnings :     2 reported,     0 suppressed
Messages :     3 reported,     0 suppressed

Mindegyik üzenet jogos és helyén való. Ahol dupla hiba van ott két üzenet is olvasható a hiba jellegének megfelelően.

Bocsi, legközelebb figyelek!

Annyit mondhatok, hogy így már van értelme az üzeneteknek! Sajnos az üzenetek száma visszatért 1201-re, de az ANSELA kezelése is minden szempontból jó. Ráadásul ott van a helyes címzés is, ami mentesít az időtrabló keresgéléstől! Nem is tudom hogyan fejezzem ki, de roppantul meg vagyok elégedve! Ehhez már nem lekapcsolni kell az üzeneteket, hanem megírom az assume makrókat. (Majd jelentkezem.) Kíváncsi vagyok sikerül-e azt a kb. 1db hibát megtalálnom, amit hosszas keresgélés után sem sikerült.

Most már csak az a kérdés, ha a blokkban explicit a BSR értéke vagy a félrecímzés egyértelmű, akkor miért csak message és nem error? Megérdemelné a jogot! ;)

... miért csak message és nem error?
Egyszerűen azért mert ez egy öröklött dolog. Nem néztem utána de feltételezem hogy az mpasmx is ugyanígy üzen (ezen a sorszámon és ez ott is "message" lehet). Ez nekem is többször piszkálta már a csőrömet, de nem akartam hogy vircsaft legyen belőle. A franc tudja hogy milyen IDE felületek alól használják a gputils csomagot. Ha be van drótozva az üzenet száma akkor meghülyülhet valami ha megváltoztatom az üzenet "besorolását" és ezzel a sorszámát. Néhány üzenet tartalmát már így is módosítottam az idők során, de emiatt még nem volt panasz. Egyszerűen nem tudom hogy mi lenne ha még jobban belekavarnék. Ezért nem nyúltam még hozzá.

Igazságod vagyon. :-) Ám legyen, "mpasm-compatible" módban marad a régi viselkedés, normál módban pedig meg fogom változtatni néhány üzenet besorolását.

------ szerk. ---------

Ha gpasm módban működik a fordító akkor az "-S1" és "-S2" kapcsolók használatával "szintet" lép a bank eléréssel kapcsolatos üzenet. Vagyis "warning" illetve "error" lesz az eddigi "message" helyett. Ebből kifolyólag más lesz a hozzá kapcsolt kód is.

gputils-src-20160710-1238.tar.bz2
gputils-20160710-1238-setup.exe

Máris töltöttem!

Még mindig keveredik a -1 és a 0f.
Vagyis mi az alapja call után ennek az üzenetnek?

Message[1302]: RAM Bank undefined in this chunk of code. Ensure that bank bits are correct. Assuming bank 15 from now on.

Az "Assuming" egy olyan dolog, hogy az ombuccman' is megdícsérne! ;) Nem tételezed fel a program írójáról, hogy hülye. Ilyenkor az automatikusan értéket kapott __ACTIVE_BANK_ADDR miatt a következő - esetleg jó - címzés hibadetektálása megfordul. (Tesztelés: a kis programomban a "movlb 4" helyet írjál "movlb 5"-öt és vizsgáld a Bank4DataManipulation üzeneteit -S 2 opció mellett!)
Természetesen a programozó - a programot tyúklépesben írva - mindig az első hibát javítja, így nem fog jelentkezni a téves üzenet.
8X---
Közben van már egy móricka makróm:

#define NOTHING -1
assume  macro   regN,regV
        if ( regN == BSR )
__ACTIVE_BANK_ADDR=regV
        endif
        endm

Ez a szubrutin elején kiüti a nem definiált vagy a fordító által rosszul értelmezett bsr miatti üzenetet.

Ha lenne egy __ACTIVE_BANK_ADDR_GLOBAL, akkor ezt helyesen beállítva felülbírálhatná pl. a call utáni __ACTIVE_BANK_ADDR törlését. Mivel nincs proc-endp, mint az MASM-ben, erről a programozónak kellene gondoskodni, hogy kijelölje a kód blokkokat.

Vagyis mi az alapja call után ennek az üzenetnek?
Megválaszoltad saját magadnak: :-)
...felülbírálhatná pl. a call utáni __ACTIVE_BANK_ADDR törlését.

Amikor írtam a bank és a page kijelölések követését akkor próbáltam követni bizonyos szabályszerűségeket. Ilyen például az hogy egy call után törlöm a bank hozzárendelést, mivel a jó ég tudja hogy mit művel a szubrutin. Lehet hogy nem nyúl a bank kijelöléshez, de az is lehet hogy összekutyulja. Ezt csak szimulátorral lehetne követni. (A gpdasm primitív szinten valami hasonlót művel, de a gpasm-ba nem lenne értelme ilyet tenni, ezért maradt az egyszerűbb megoldás.) Persze mivel van pár év programozási gyakorlatom, pont a hibakezelés az ami nem mindig sikerül kimerítően, mivel akadnak olyan hibák amiket már csak reflexből is elkerülök és fel sem merül bennem hogy azokat valaki el fogja követni. Aztán legközelebb mégis belefutok egy ordas hibába a saját kódomban. :-)

A törlés úgy működik hogy minden utasításhoz van pár jelző amelyek közül az egyik mutatja hogy a végrehajtása után érvényes lehet-e még egy bank kijelölés, vagy el kell felejteni. A vezérlés átadások - bra, call, goto, return, stb. - ilyenek.

Ha lenne egy __ACTIVE_BANK_ADDR_GLOBAL, akkor ezt helyesen beállítva felülbírálhatná pl. a call utáni __ACTIVE_BANK_ADDR törlését.

Ezt végül is megcsinálhatod makrókkal is, vagy jobban szeretnéd ha a gpasm segítene a változók kezelésében? ;-)

Mivel nincs proc-endp, ...

Ezt én is furcsálltam amikor annak idején ismerkedtem a gpasm nyelvi elemeivel. (Néha jól jönne egy blokk lezárás.)

Egyébként most frissítettem a gputils változás naplóját: The major changes since the stable release (1.4.2)
Van pár új dolog ami esetleg téged is érdekelhet.

Van pár új dolog ami esetleg téged is érdekelhet.
Nem igazán. Elkerülte a figyelmedet, hogy folyamatosan a snapshot-ot használtam. ;)
Sőt, közben a frissített doksit is olvasgattam.
Ráadásul nem csak tesztelgettem, hanem ezzel dolgozok.
Igazán nem mondhatod, hogy nem bízom a munkádban!

Ilyen például az hogy egy call után törlöm a bank hozzárendelést, mivel a jó ég tudja hogy mit művel a szubrutin.
Igen, ezeket olvastam a doksiban, de anélkül is tudtam, mert ez a helyes megoldás.
Most, amikor elkészült a release, és kicsit pihentél, megnézhetnéd újra miket írtam erről. (pl. #pragma isolated_call) Persze asm esetén elég ciki lenne minden call, stb. elé írni a deklarációt. Nem látszana a kód!

Ezt végül is megcsinálhatod makrókkal is, vagy jobban szeretnéd ha a gpasm segítene a változók kezelésében? ;-)
Ha az __ACTIVE_BANK_ADDR törlődik pl. call után, akkor nem tudom megakadályozni a következő felesleges üzenetet vagy hibát!

#define NOTHING __BANK_INV
        call Subr
;jelenlegi megoldás
        __ACTIVE_BANK_ADDR=NOTHING
;helyette ezt kellene tennie a fordítónak (pl.) call után
if ( __ACTIVE_BANK_ADDR_GLOBAL == NOTHING )
        __ACTIVE_BANK_ADDR=NOTHING
endif
;egyéb esetekben ...,b esetén
if ( __ACTIVE_BANK_ADDR == NOTHING )
        __ACTIVE_BANK_ADDR = __ACTIVE_BANK_ADDR_GLOBAL
endif
;és ha az is NOTHING, akkor jöhet az üzi ;)

Ezt nem lehet makróval megcsinálni!
(Ez nem teljesen igaz. Lehetne kapcsolgatni az errorlevel-t. Ennek az őszinte megtételéhez közel annyi vizsgálatot kellene megtenni, mint a fordító. Tehát ez sem jó!)
Lehetne egy pótvizsgálat:
- a call előtt elmenteni az __ACTIVE_BANK_ADDR értékét
- a call utáni vizsgálat összehasonlítja a mentett és és globális értéket
- eltérés esetén üzenet => Erre csak akkor van szükség, ha nem a fordító kezeli az assume direktívát.
Belegondolva, elegendő lenne, ha a fordító kezelné az assume direktívát - ekkor nincs szükség globális változóra.
Miről is beszélek? A program úgy készül, hogy írása közben próbálom minimalizálni a bármilyen üzenetek számát. Ha a fordító üzen, hogy nem biztos a helyes címzésben, akkor odaírok egy assume-t. Ezzel megszűnik az üzenet. Ha valahol nem jól állítom be a címzést, akkor átvertem a fordítót. Hazudtam, de ez az én büntetőjogi felelősségem. ;)
Ezzel szemben, jelenleg a fordító feltételez, és ezzel elromlik a címzés, amivel további hibás üzenetek keletkeznek. Ez azért rosszabb, mert csak újabb utasítással (+kód) tudom feloldani. Az 1200db üzenetből kiindulva, közel ennyi helyen kellene módosítanom a kódot, hogy minden esetben elmagyarázzam a helyes címzést!

A proc-endp hiánya nem annyira meglepő. Az x86-hoz képest ezek a processzorok a stack frame-et csak szoftverből tudják emulálni. No, ez sem meglepő, mert inkább vezérlésre készültek, mint magasszintű struktúrált kód végrehajtására. A procedúrát nézve alapszabály az egyetlen be- és kilépési pont, azaz a befejezéshez el kell ugrani a procedúra végén levő stack frame takarító kódig. Csak utána jöhet a return.
Vezérlésnél az ember logikus sorrendben végzi a vizsgálatokat, igyekezve minél előbb visszatérni a hívásból. Így ki lehet hagyni az adott helyzetben felesleges kódot, amit azért kell megtenni, mert nincs idő.

Ugyan ez igaz a stack frame/lokális változók kezelésére. Pl. a C-ben megírt USB drivert dolgoztam át úgy, hogy majdnem az összes változót kitöröltem. :) A paraméterek átadásához "emulálom" a sokregiszteres processzort, aminek van pl. R0..R5 scratchpad regisztere - az access területen. Ehhez meg kellene egy időtrabló pusha utasítás interrupt esetére. Ezért interrupt alatt - ahol a kód jó része fut - az r0..r5 regisztereket használom - esetleg az egyetlen bank területen, mert az acces már elfogyott. Bizonyos szemszögből ez pazarlónak tűnhet, de ez a konvenció gyorsabb és rövidebb kódot eredményez kevesebb memória felhasználásával.

Néha jól jönne egy blokk lezárás.
No, igen. Mégsincs probléma ezzel. Ugyanaz a szituáció, amikor x86-ra nem struktúrált programot írsz. A proc és endp között olyan kód van, amikor "nem csak a kijáraton lehet kihajtani".
Hova helyeznéd a blokkhatárt a proc1 és proc2 esetén, ha az alábbi végrehajtási sorrendek lehetségesek?
- call proc1 -> return
- call proc1 -> jump proc2 -> return
- call proc2 -> return

Nem igazán. Elkerülte a figyelmedet, hogy folyamatosan a snapshot-ot használtam.
Ez ma sajnos nem fog sikerülni. A sourceforge.net lehalt, nem tudtam commit-olni.

Sőt, közben a frissített doksit is olvasgattam.
A szöveg minősége miatt elnézést kérek. Pocsék az angol tudásom. Elég tűrhetően szoktam fogalmazni, de ez angolul nagyjából a nyelv kerékbe törésének felel meg. Ha csak lehet akkor elkerülöm a dokumentáció írását.

Az assume megvalósításán gondolkozom. Jó ötlet a kijelölt bank mentése és visszaállítása.

Én is csináltam már olyat hogy egy eljárás végén ugrással adtam át a vezérlés egy másik eljárásra hogy majd az térjen vissza a hívóhoz. A módszer csökkenti a verem használatot, persze nem lehet ész nélkül használni.

Ehelyett:


    .
    .
    call proc2
    return

Ez lett:


    .
    .
    goto proc2

Technikai okoból új bekezdésbe írom az assume tesztelés eredményét - amire sajnos néhány napot várni kell.
Cserébe azonnal kerül az éles kódba.
8X---
És nem is! :)

Tanusítom: Ekészült az "assume global"!
A doksiban viszont kiemelhetnéd, hogy ez globális, egyszer megadható és nem változtatható érték! (Értem én, a default is ezt jelenti. ;))
A kis makrómat meg átnevezem jó magyarosan assume_local-ra. ;)
Ezzel minden problémám megoldódni látszik. Mégegyszer elmondom: Ezzel eltűnt 1200 felesleges, semmitmondó és hibás üzenet. Méghozzá olyan módon, hogy nem kell minduntalan felesleges - és esetleg felesleges kódot generáló - direktívákkal szórakoztatni a fordítót! Ráadásul az SFR és acces kezelés is megjavult. Tehát olyan módon, hogy nem korlátozok semmit az errorlevel-lel!

Sajnos csak jövő héten jutok hozzá egy másik programhoz, amelyben reményeim szerint az új lehetőségekkel esetleg megtalálom a "várva várt" hibát.

Az angol tudásoddal szerintem nincs baj. Én csak olvasok, de régebben apám műszaki fordításait lektoráltam. Ennek ellenére gyerekeimet (felsőfokúval, gyakorlattal rendelkeznek) néha kijavítgatom akár nem informatikai kifejezések használatában is.

A doksiban viszont kiemelhetnéd, hogy ez globális, egyszer megadható és nem változtatható érték!
Hát nem az, annyiszor módosítod ahányszor akarod. Nem akartam korlátozni.

Az angol tudásoddal szerintem nincs baj.
Látnád hogy néha mit össze tökölök a Google Fordító, a Bing Translator és a Webfordítás oldalakkal azért hogy összehozzak egy-egy tűrhető mondatot. Érdekes módon gyakran észreveszem azt hogy ha a fordítás során valami baromság kerekedik a magyar mondatból. Ekkor nekiállok görcsölni egészen addig amíg a magyarra visszafordított mondat elég érthető nem lesz.

Sajnos azzal vagyok megverve hogy a memóriám olyan mint egy lyukas szita. Egészen fiatalon is az volt velem, ha a családom bevett volna pl. valamilyen egyszerű kártyajátékba és nekiálltak elmondani azt a pár szabályt, képtelen voltam megjegyezni, azt meg pláne nem hogy milyen lapok vannak még kézben. Vagy sakkoztunk és nem tudtam előre gondolkozni, ez képtelen és lehetetlen vállalkozásnak látszott számomra. Játszottunk én meg - jobb híján - léptem ahogy éppen sikerült és mindig veszítettem, végül persze ezen feldühödtem és megkaptam az értékelést: "Veled nem lehet játszani!" Mindezek ellenére ha megvan a feladat és békén hagynak dolgozni akkor képes vagyok beleásni magam annyira hogy egészen jól elboldogulok. De a nyelvtanulásra az előbbi tapasztalataim miatt nem is gondolok.

Hát nem az, annyiszor módosítod ahányszor akarod. Nem akartam korlátozni.
Rossz hírem van! Akkor ez nagyon nem működik.
Pedig örültem amikor megértettem.
Szerintem jó ez így. Bár, ha a program több fix bank állású részt tartalmaz, akkor praktikus lehet - nem csak rám van kihegyezve.
Szóval ma nem, de felrakok megint egy tesztprogramot, ha kell.

A memóriáddal meg kevered a dolgokat. Inkább agyi önvédelem, ;) Ha valami nem érdekel, akkor képtelen vagy megjegyezni. Nálunk az asszony PROGRAMOZTA a mosógépet. Válás után a sajátomat kiválóan kezeltem. Jelenlegi párommal hasonló a hejezet, ehhez a géphez csak ő ért. :)

Okkal voltam óvatos amikor felvettem a kézikönyvbe az assume leírását. Ezért van a végén a figyelmeztetés arra hogy ez még kisérleti állapotban van. ;-) Még csak ketten teszteltük és máris felbukkant egy hiba. :-/ Két helyen elmaradt egy ellenőrzés ami különleges esetként értelmezi a negatív értéket. Ezért az assume a negatív értéket is érvényes bank kijelölésnek tekintette. Ez jelen esetben a 15. bankra mutatott. Már commit-oltam a javítást. Itt egy kis példa program, ami az assume hatását szemlélteti:


	processor 18f24k50
	radix	dec
	include <p18f24k50.inc>

    cblock	0x400
	Bank4:0
    endc

    cblock	0x500
	Bank5:0
    endc

	org	0

;----------------------------------------------------------------------------------

    messg "A \"banksel Bank4\" előtt ------- __ACTIVE_BANK_ADDR: #v(__ACTIVE_BANK_ADDR)"
	banksel	Bank4
    messg "A \"banksel Bank4\" után -------- __ACTIVE_BANK_ADDR: #v(__ACTIVE_BANK_ADDR)"
	call	function0
    messg "A \"call function0\" után ------- __ACTIVE_BANK_ADDR: #v(__ACTIVE_BANK_ADDR)"

	banksel	Bank5
    messg "A \"banksel Bank5\" után -------- __ACTIVE_BANK_ADDR: #v(__ACTIVE_BANK_ADDR)"
	call	function1
    messg "A \"call function1\" után ------- __ACTIVE_BANK_ADDR: #v(__ACTIVE_BANK_ADDR)"

;----------------------------------------------------------------------------------

	assume	Bank4
    messg "Az \"assume Bank4\" után -------- __ACTIVE_BANK_ADDR: #v(__ACTIVE_BANK_ADDR)"
	banksel	Bank4
    messg "A \"banksel Bank4\" után -------- __ACTIVE_BANK_ADDR: #v(__ACTIVE_BANK_ADDR)"
	call	function0
    messg "A \"call function0\" után ------- __ACTIVE_BANK_ADDR: #v(__ACTIVE_BANK_ADDR)"

	banksel	Bank5
    messg "A \"banksel Bank5\" után -------- __ACTIVE_BANK_ADDR: #v(__ACTIVE_BANK_ADDR)"
	call	function1
    messg "A \"call function1\" után ------- __ACTIVE_BANK_ADDR: #v(__ACTIVE_BANK_ADDR)"

;----------------------------------------------------------------------------------

	assume	Bank5
    messg "Az \"assume Bank4\" után -------- __ACTIVE_BANK_ADDR: #v(__ACTIVE_BANK_ADDR)"
	banksel	Bank5
    messg "A \"banksel Bank4\" után -------- __ACTIVE_BANK_ADDR: #v(__ACTIVE_BANK_ADDR)"
	call	function0
    messg "A \"call function0\" után ------- __ACTIVE_BANK_ADDR: #v(__ACTIVE_BANK_ADDR)"

	banksel	Bank4
    messg "A \"banksel Bank5\" után -------- __ACTIVE_BANK_ADDR: #v(__ACTIVE_BANK_ADDR)"
	call	function1
    messg "A \"call function1\" után ------- __ACTIVE_BANK_ADDR: #v(__ACTIVE_BANK_ADDR)"

;----------------------------------------------------------------------------------

	assume	__BANK_INV
    messg "Az \"assume __BANK_INV\" után --- __ACTIVE_BANK_ADDR: #v(__ACTIVE_BANK_ADDR)"
	banksel	Bank5
    messg "A \"banksel Bank4\" után -------- __ACTIVE_BANK_ADDR: #v(__ACTIVE_BANK_ADDR)"
	call	function0
    messg "A \"call function0\" után ------- __ACTIVE_BANK_ADDR: #v(__ACTIVE_BANK_ADDR)"

	banksel	Bank4
    messg "A \"banksel Bank5\" után -------- __ACTIVE_BANK_ADDR: #v(__ACTIVE_BANK_ADDR)"
	call	function1
    messg "A \"call function1\" után ------- __ACTIVE_BANK_ADDR: #v(__ACTIVE_BANK_ADDR)"

;----------------------------------------------------------------------------------

	bra	$

function0:
	return

function1:
	return

	end

A lista ide vonatkozó része:


                      00003 ;==========================================================================
                      00004 ; Build date : Oct 21 2015
                      00005 ;  MPASM PIC18F24K50 processor include
                      00006 ; 
                      00007 ;  (c) Copyright 1999-2015 Microchip Technology, All rights reserved
                      00008 ;==========================================================================
                      00009 
                      02166         LIST
                      00004 
                      00005     cblock      0x400
  00000400            00006         Bank4:0
                      00007     endc
                      00008 
                      00009     cblock      0x500
  00000500            00010         Bank5:0
                      00011     endc
                      00012 
000000                00013         org     0
                      00014 
                      00015 ;----------------------------------------------------------------------------------
                      00016 
Message[301]: MESSAGE: "A "banksel Bank4" előtt ------- __ACTIVE_BANK_ADDR: -1"
                      00017 -1
000000 0104           00018         banksel Bank4
Message[301]: MESSAGE: "A "banksel Bank4" után -------- __ACTIVE_BANK_ADDR: 1024"
                      00019 1024
000002 EC19 F000      00020         call    function0
Message[301]: MESSAGE: "A "call function0" után ------- __ACTIVE_BANK_ADDR: -1"
                      00021 -1
                      00022 
000006 0105           00023         banksel Bank5
Message[301]: MESSAGE: "A "banksel Bank5" után -------- __ACTIVE_BANK_ADDR: 1280"
                      00024 1280
000008 EC1A F000      00025         call    function1
Message[301]: MESSAGE: "A "call function1" után ------- __ACTIVE_BANK_ADDR: -1"
                      00026 -1
                      00027 
                      00028 ;----------------------------------------------------------------------------------
                      00029 
                      00030         assume  Bank4
Message[301]: MESSAGE: "Az "assume Bank4" után -------- __ACTIVE_BANK_ADDR: -1"
                      00031 -1
00000C 0104           00032         banksel Bank4
Message[301]: MESSAGE: "A "banksel Bank4" után -------- __ACTIVE_BANK_ADDR: 1024"
                      00033 1024
00000E EC19 F000      00034         call    function0
Message[301]: MESSAGE: "A "call function0" után ------- __ACTIVE_BANK_ADDR: 1024"
                      00035 1024
gpasm-1.4.6 #1248 (Jul 15 2016)      main.asm   7-15-2016  21:04:06         PAGE  2


LOC    OBJECT CODE    LINE  SOURCE TEXT
  VALUE

                      00036 
000012 0105           00037         banksel Bank5
Message[301]: MESSAGE: "A "banksel Bank5" után -------- __ACTIVE_BANK_ADDR: 1280"
                      00038 1280
000014 EC1A F000      00039         call    function1
Message[301]: MESSAGE: "A "call function1" után ------- __ACTIVE_BANK_ADDR: 1024"
                      00040 1024
                      00041 
                      00042 ;----------------------------------------------------------------------------------
                      00043 
                      00044         assume  Bank5
Message[301]: MESSAGE: "Az "assume Bank4" után -------- __ACTIVE_BANK_ADDR: 1024"
                      00045 1024
000018 0105           00046         banksel Bank5
Message[301]: MESSAGE: "A "banksel Bank4" után -------- __ACTIVE_BANK_ADDR: 1280"
                      00047 1280
00001A EC19 F000      00048         call    function0
Message[301]: MESSAGE: "A "call function0" után ------- __ACTIVE_BANK_ADDR: 1280"
                      00049 1280
                      00050 
00001E 0104           00051         banksel Bank4
Message[301]: MESSAGE: "A "banksel Bank5" után -------- __ACTIVE_BANK_ADDR: 1024"
                      00052 1024
000020 EC1A F000      00053         call    function1
Message[301]: MESSAGE: "A "call function1" után ------- __ACTIVE_BANK_ADDR: 1280"
                      00054 1280
                      00055 
                      00056 ;----------------------------------------------------------------------------------
                      00057 
                      00058         assume  __BANK_INV
Message[301]: MESSAGE: "Az "assume __BANK_INV" után --- __ACTIVE_BANK_ADDR: 1280"
                      00059 1280
000024 0105           00060         banksel Bank5
Message[301]: MESSAGE: "A "banksel Bank4" után -------- __ACTIVE_BANK_ADDR: 1280"
                      00061 1280
000026 EC19 F000      00062         call    function0
Message[301]: MESSAGE: "A "call function0" után ------- __ACTIVE_BANK_ADDR: -1"
                      00063 -1
                      00064 
00002A 0104           00065         banksel Bank4
Message[301]: MESSAGE: "A "banksel Bank5" után -------- __ACTIVE_BANK_ADDR: 1024"
                      00066 1024
00002C EC1A F000      00067         call    function1
Message[301]: MESSAGE: "A "call function1" után ------- __ACTIVE_BANK_ADDR: -1"
                      00068 -1
                      00069 
                      00070 ;----------------------------------------------------------------------------------
                      00071 
000030 D7FF           00072         bra     $
                      00073 
000032                00074 function0:
000032 0012           00075         return
                      00076 
gpasm-1.4.6 #1248 (Jul 15 2016)      main.asm   7-15-2016  21:04:06         PAGE  3


LOC    OBJECT CODE    LINE  SOURCE TEXT
  VALUE

000034                00077 function1:
000034 0012           00078         return
                      00079 
                      00080         end

Most már nem állítok semmit csak kérdezek, mint Erich von Däniken. ;)

Itt alant a kis programomban: (-f -X -S 2)
A HpInterrupt honnan tudja, hogy a Bank4 jó? (se banksel, se assume)
A Start után hogyan lesz az __ACTIVE_BANK_ADDR Bank4? (van előtte egy return, banksel Bank15 - de a legelején, és assume Bank15)

#include <P18F24K50.INC>
		list n=0, st=off

;RAM
		cblock	400
		Bank4:0
		Bank4_data
		endc

		cblock	500
		Bank5:0
		Bank5_data
		endc
;SFR
		cblock	0f00
		Bank15:0
		endc
;code
		org		0
		banksel	Bank15
		goto	Start
;Interrupt
		org		8
;	assume	 Bank4
HpInterrupt
;		movf	ANSELA, w, b
		movf	Bank4_data, w, b
;		movf	Bank5_data, w, b
		retfie	FAST
		
Bank4test
;		movf	ANSELA, w, b
		movf	Bank4_data, w, b
;		movf	Bank5_data, w, b
		return
;entry
Start
	assume	Bank15
	messg "__ACTIVE_BANK_ADDR: #v(__ACTIVE_BANK_ADDR/100)"
;->Message[301]: MESSAGE: "__ACTIVE_BANK_ADDR: 4"
;		banksel	Bank15
;->Error[1507]  : Register in operand not located in RAM Bank 4. Ensure that Bank bits are correct: 'ANSELA' (Addr: 0x0F5B; Bank_15: 0x0F00; Offs: 0x005B)
		movf	ANSELA, w, b
;		movf	Bank4_data, w, b
;		movf	Bank5_data, w, b
	assume	Bank4
	banksel	Bank4
		call	Bank4test
;		movf	ANSELA, w, b
		movf	Bank4_data, w, b
;		movf	Bank5_data, w, b
;		banksel	Bank5
		call	Bank4test
;		movf	ANSELA, w, b
		movf	Bank4_data, w, b
;		movf	Bank5_data, w, b
Loop
		bra		Loop
		end

Elnézést kérek. Egy darabig nézegettem hogy válaszolsz-e és nem vettem észre hogy van egy kérdésed. Ráuntam és egy ideig nem törődtem a bloggal. :-( Ma lestem meg újból hogy mi a helyzet. Kipróbáltam a mintaprogramodat. Az a helyzet hogy ez egy bug, amiről még jó ideig nem szerzek tudomást ha nem jelzed. A gpasm két menetben fordít. Az assume már az első menetben is érvényre jut amivel nincs is baj, de a második menet indítása előtt ezt alaphelyzetbe (-1) kéne állítani. Ezt hagytam ki a kódból. Most legalább lesz egy RC4 kiadás is. :-)

Ne kérj elnézést! Ha a munkatársaim lennének tizedennyire készségesek és ötször trehányabbak, nos akkor másik bolygón élnénk. :( (Tudod: ez dícséret volt! :))

Viszont rossz hírem van. Talán lesz RC5 is!

A probléma a következő: (Szintén a teszt programomban. Nem rakom ide mégegyszer a forrást.)
Tesztelve: gpasm-1.5.0 #1279 (Aug 10 2016)
Ha sorbamegyünk a sorokon, akkor az alábbi teljesen jó:

        assume   Bank4
HpInterrupt
Message[1302]: RAM Bank undefined in this chunk of code. Ensure that bank bits are correct. Assuming bank 4 from now on.
        movf    Bank4_data, w, b

Viszont ez a részlet sántít:

...
                return
Start
                assume  Bank15
Message[301]: MESSAGE: "__ACTIVE_BANK_ADDR: 4"
Warning[1206]: Register in operand not located in RAM Bank 4. Ensure that Bank bits are correct: 'ANSELAb' (Addr: 0x0F5B; Bank_15: 0x0F00; Offs: 0x005B)
                movf    ANSELA, w, b

Sorrendben nézve:
banksel 15
assume Bank4
Bank4 címzés -> helyesen jön a ...Assuming bank 4 from now on.
return -> itt törölni kellene az __ACTIVE_BANK_ADDR értékét!
assume Bank15
Bank15 címzés -> hibásan jön a ...Register in operand not located in RAM Bank 4.

A hiba vélhető oka az, hogy a return nem semmisíti meg az "assume Bank4" (vagy akár banksel) miatt létrejött __ACTIVE_BANK_ADDR=Bank4 értékadást.
Másrészt az "assume Bank15" nem jut érvényre, mint a kód elején, amikor vélhetően az __ACTIVE_BANK_ADDR=-1 volt érvényben. Ha ezt a return törölné, akkor az assume lenne érvényes!

Szóval úgy látom, még mindig felülírod az __ACTIVE_BANK_ADDR értékét az assume értékével, de csak ha az előbbi -1.

Kellene egy __ASSUMED_BANK_ADDR.
A return "család" törölje az __ACTIVE_BANK_ADDR értékét, de az __ASSUMED_BANK_ADDR maradjon változatlan!
(Esetleg a programban külön törölni kell az __ACTIVE_BANK_ADDR értékét.)
A fenti példában jók lennének az üzenetek, ha a címkezelés így nézne ki:

if ( __ACTIVE_BANK_ADDR != __BANK_INV )
    címkezelés
else
    if ( __ASSUMED_BANK_ADDR != __BANK_INV )
        címkezelés az assume értékével
    else
        bank undefined

Az így keletkező üzenetek jók lesznek és megfelelő assume használattal megoldja az általam local/global-nak nevezett assume kezelést is.

"Szóval úgy látom, még mindig felülírod az __ACTIVE_BANK_ADDR értékét az assume értékével, de csak ha az előbbi -1."
Eddig azt hittem hogy tudom miről van szó, de most teljesen összezavartál és már nem értem ezt az egészet. Ha az assume értékét nem használnám semmire akkor az assume direktíva csak bohóckodásra lenne jó. Tehát arra kérlek hogy írj le egy szabályrendszert ami megmutatja az __ACTIVE_BANK_ADDR és az __ASSUMED_BANK_ADDR egymáshoz való viszonyát, azt hogy szerinted melyik mikor legyen érvényes és mit mutasson a hozzájuk tartozó direktívával összefüggésben.

:)
Feljebb pont ott van az algoritmus, de azért kifejtem egy kicsit.

0. Az alábbiak a BSR-rel történő direkt címzés helyességének megállapításához kell alkalmazni.
1. Az __ACTIVE_BANK_ADDR kezdeti értéke __BANK_INV. (*)
2. Az __ASSUMED_BANK_ADDR kezdeti értéke __BANK_INV. (*)
3. Az __ACTIVE_BANK_ADDR értékét be kell állítani minden banksel, vagy annak megfelelő kód esetén.
4. Az __ASSUMED_BANK_ADDR értékét be kell állítani minden assume direktívánál. Az érték lehet __BANK_INV is.
5. Az __ACTIVE_BANK_ADDR értéke __BANK_INV lesz minden goto/call/bra/return/retfie (ezt talán jobban tudod, hogy még mi) után, kivétel a call s,FAST (ha van ilyen).
6. A címzés helyességének megállapításakor az __ACTIVE_BANK_ADDR értékét kell használni, ha != __BANK_INV.
7. Ha a címzés helyességének megállapításához __ACTIVE_BANK_ADDR nem használható, akkor az __ASSUMED_BANK_ADDR értékét kell használni, ha != __BANK_INV.
8. Ha a címzés helyességének megállapításához az __ASSUMED_BANK_ADDR sem használható, akkor a használt bank meghatározatlan, és ennek megfelelően kell eljárni.

(*) A hardver reset (POR, BOR) - ha minden igaz - törli a BSR értékét. Ennek alapján a kezdeti érték lehetne 0 is. Ennek ellenére nem javaslom ezt a beállítást, mivel tetszőleges BSR érték mellett több féle módon kerülhet a program a reset vektorra.

Egyszerű szöveges magyarázat:
Ha a BSR-en keresztül történő direkt címzéshez nincs explicit cím (nem volt banksel, vagy invalidálódott az értéke), akkor meg kell vizsgálni a programozó által javasolt BSR értékkel (assume) helyes-e a címzés. A javasolt címet nem szabad úgy kezelni, mintha banksel lett volna.

A fentiek alapján az assume használható globálisan, párban a banksel mellett, vagy egyedileg az egyes blokkokban. Ha a program egy rövid szakaszán pl. egy call "kiüti" az előző banksel értékét a párhuzamosan alkalmazott assume kikapcsolja a felesleges hibaüzeneteket. Ekkor a program irója garantálja a call "isolated" tulajdonságát.

Természetesen a
banksel Bank4
assume Bank3
esetén a programozó hülye! ;)

"7. Ha a címzés helyességének megállapításához __ACTIVE_BANK_ADDR nem használható, akkor az __ASSUMED_BANK_ADDR értékét kell használni, ha != __BANK_INV."

Tisztán látszik hogy azért mentem be az erdőbe mert ezt a pontot kihagytam a kódoláskor. A bank kezelés ellenőrzésekor kizárólag az __ACTIVE_BANK_ADDR értékét figyeli a gpasm, mivel ragaszkodtam ahhoz az elképzelésemhez hogy az vizsgálatok alapját a valós, fizikailag is kiadott utasítások képezzék.
Ez van. Néha nem ártana lélekben kicsit hátrább lépni és úgy is megszemlélni a dolgokat, hátha sikerül mást is meglátni. :-/
Most egy darabig nem adom ki a következő RC_xx változatot, mert már kezdenek osztódással szaporodni, amit nagyon nem kéne. Jó lenne ha nem rontanám el a bank ellenőrzést jelenleg elég jól végző kódot, ezért ülök egy darabig rajta mint kappan a záptojásokon. :-)

...mivel ragaszkodtam ahhoz az elképzelésemhez hogy az vizsgálatok alapját a valós, fizikailag is kiadott utasítások képezzék.
No, pont ezt jelenti az assume: semmi ilyet ne csináljál, hanem tételezd fel (hidd azt!!).
És ez egyben a a gpasm + mikrokontrollerek eltérését adja a MASM-hez képest. Ott hiába egyértelmű a szegmensregiszter betöltése, soha nem veszi figyelembe, csak az assume által megadottat.

Nekem is lassan esett le az algoritmus. Nem is tudtam megfogalmazni pontosan a miértjét, de talán...
Lényegében a két direktíva (hanyagoljuk el, ha az egyik még kódot is generál!) keverése nem célszerű pont azért, mert különböző dolgokra vonatkoznak. A prioritás természetesen a banksel-é, amíg megbízható.

Jó lenne ha nem rontanám el a bank ellenőrzést...
Biztosan nem fogod! Ez egyszer már működik, és a két direktíva a prioritás miatt nem fog keveredni.

Raktam fel msys-t, most már akár fordítani is tudok. Ha lesz rá időm. :(

A tárolóban van a javított kód. Mellesleg javasolom azt hogy ha a választott bank sorszámát szeretnéd kiíratni akkor ne így tedd:

messg "__ACTIVE_BANK_ADDR: #v(__ACTIVE_BANK_ADDR/100)"

Ez ugyanis nullát ad akkor ha a bank értéke -1 (__BANK_INV). (Ráadásul ha egy szám leírásakor nem adod meg a használt számrendszert akkor jól ki is tolhatsz magaddal: 100 --> 0x100) Ha viszont az erre is alkalmas __BANK_SHIFT állandót használod akkor a mínusz egyből nem lesz nulla, amivel aztán becsapod magadat.


messg "__ACTIVE_BANK_ADDR: #v(__ACTIVE_BANK_ADDR >> __BANK_SHIFT)"

Ezt ráadásul egyszerűsítheted is a következő módon. Valahol a kód elején felveszed a következő két definíciót:


#define ActiveBank	(__ACTIVE_BANK_ADDR >> __BANK_SHIFT)
#define AssumedBank	(__ASSUMED_BANK_ADDR >> __BANK_SHIFT)

Aztán használod őket:


	messg "__ASSUMED_BANK: #v(AssumedBank)"
	messg "__ACTIVE_BANK: #v(ActiveBank)"

Biztosan elrontottál valamit! ;)
Mert eddig tökéletesnek néz ki, a hibaüzenetek is a helyükön vannak.

A programom eddig is így kezdődött és néhány utasítástól eltekintve csak a Bank4-et használom.

000000                00321             org         0
                      00322         assume  Bank4
000000 6AF8           00323             clrf        TBLPTRU, a
000002 010F           00324             banksel     Bank15                  ;switch to unmapped SFR region
Message[301]: MESSAGE: "__ASSUMED_BANK: 4"
                      00325 4
Message[301]: MESSAGE: "__ACTIVE_BANK: 15"
                      00326 15
000004 EF6D F002      00327             goto        Start
                      00328 
000008                00329             org         8
Message[301]: MESSAGE: "__ASSUMED_BANK: 4"
                      00330 4
Message[301]: MESSAGE: "__ACTIVE_BANK: -1"
                      00331 -1
000008                00332 Interrupt

A továbbiakban - ha bankot használtam - nem lehetett a hibaüzenetek kikapcsolása nélkül fordítani.
(Lehetett, csak volt több mint 1200 üzenet.)
Így viszont nincsenek felesleges üzenetek és még látszik is, hogy miért.
Igazán szép munka, és ezzel újabb lépést tettünk az MPASM hátunk mögött hagyása felé! :)

Köszönöm hogy kipróbáltad. Akkor még ma kiadok egy újabb - remélhetőleg az utolsó - RC változatot. Aztán ha minden jól megy némi pihentetés után ez lesz a release is.

-----------------------------

Egyébként kíváncsi vagyok a becsapódásra a gpsim project részéről. Pár hete egy vizsgálat közben felfedeztem hogy a Microchip-féle mp2cod segédprogram olyan COD fájlt készít amiben a forráskód hivatkozások nevét 255 bájton tárolja (ami egy 256 bájtos tömböt jelent). A gpasm és a gplink mindezt 63 bájton tette eddig. Módosítottam a kód ide vonatkozó részeit úgy hogy ugyancsak 255 bájt legyen a hivatkozások legnagyobb hossza. A gpvc programot meg úgy hogy mindkét hosszal elboldoguljon. A változtatás tényéről értesítettem Roy Rankint azon a címen ami a gpsim ChangeLog-jában van. Tojt az egészre, nem is válaszolt. :-/ Lesz majd vakaródzás ha kapják a reklamációkat.

Szivesen. Bármikor nyugodtan szóljál, amint tudom tesztelem - ugyan csak abszolút módban és pic18 platformon. Mindenesetre a 8k-s bináris bitre pontosan ugyanaz lesz. Ez a legfontosabb tesz, mert - ugyan kis sorozatban - azonnal kerül a program a termékbe.

Nem leszek ám mindig ennyire barátságos! Elatároztam, hogy addig ütlek, amíg nem lesz egy pic24 fordítónk! ;) Tudom, már megbeszéltük, de hátha összejön.

Sokkal fontosabb lenne, mint a gpsim. Nemrég kérdeztem valakitől, hogy mire használja. Tehát inkább olyan "amire én használom arra jó - linuxon" és nem production kategória. Különösen a deklarált hibái/hiányosságai és a gyenge cpu támogatottság miatt. Bezzeg a breadboard viewer, no az valami! Ebből is láthatod, hogy csak játék.

Valami 4fonya nevű user állította, hogy a gyártónak úgy is jobb van. ;) Újabb tény derült ki, ami ezt cáfolja! A probléma egyszerű: a meglévő PM3 sorozatprogramozót szerettük volna használni 28 érintkezős sockettel a sorozatgyártáshoz. A mai napig árulják, és ehhez a cpu-hoz való, igaz másik socket kellene, ami maga 55eFt.
De.
Az egyébként 28-as socket a kicsit eltérő LVP kezelés miatt használhatatlan.
Ehhez a típushoz ajánlott socket meg obsolete - több éve nem gyártják.
Felrakva az MPLAB X mellé adott firmware-t, már a cpu-t sem ismeri, csak az egy számmal nagyobbat.
Úgy döntöttem, erre nekem nics időm!
Irány az ebay, ahol a fenti nettó árért pontosan 10db pickit3 klón és 10db socket kapható. Még ha rossz minőségű is, akkor is megéri.

A gpsim sem támogatja ezt a cpu-t.

A másik csoda maga a pickit3.
A nagy memóriába nem fért bele az oprendszer, így cpu család váltáskor újratölti magát. :)
Mérni nehéz vele, mert a reset többször is megjelenik, a szemem meg kiesik amikor a rendszer feléledését mérem.
A debug mód váltásának bizonytalansága már okozott némi füstöt.
Az oprendszer meg ennél a verziónál zárt.

A gpsim helyett meg 8 csatornás logikai analizátort használok, ami csak pár ezer Ft. Néhány trigger sokkal hatékonyabb, mint a breakpont-okat kapcsolgatni. Ráadásul követlenül tudom mérni az időzítéseket és a futásidőt.

Ami a lényeg: ebben a katyvaszban a gpasm a stabil pont. Ha lenne még néhány util, akkor át lehet térni a vi editor+makrók+makefile fejlesztőrendszerre.

... addig ütlek, amíg nem lesz egy pic24 fordítónk ...
Mire ez meglesz addigra a szakállad a Holdig fog érni és mindketten túl leszünk a zsenge virágkorunkon. :-)

A másik csoda maga a pickit3.
Nekem egy MPLAB ICD2 van. Elég poros, de még bele lehet látni a műanyag tokba. :-/ Ezen kívül egy egyedileg feljavított usbpicprog alapú eszközt használtam utoljára pár éve. (Az eredeti változatban alkalmazott kapcsoló FET-eknek túl nagy volt a feszültségesésük ezért átterveztem bipoláris tranzisztorosra és persze a kapcsoló diódákat is kicseréltem 1A-es Schottky típusokra. Érdekes hogy ez másnak nem fájt csak nekem? Még mindig az eredeti kapcsolási rajz van fent. Aztán akkoriban még nem támogatta a pic18f44k22 sorozat tagjait, tehát ezeket is hozzá kellett adnom. Rég volt, talán igaz sem volt.)

A továbblépéshez szükségesnek látom a coff formátum kispadra küldését. Az elf lenne a megfelelő úgy mint más komolyabb fordítók esetében. Ez azonban már önmagában véve is jó nagy munka, mivel a gpdisasm kivételével minden programot érint. Attól függ hogyan lesz rá időm és lehetőségem. Még mindig vannak olyan részei a gpasm-nak amiknek nem ismerem eléggé a működését, pl. a makrók kezelése. Leírás persze sehol, bár ebben én sem erőltetem agyon magamat.

kapcsoló FET-eknek túl nagy volt a feszültségesésük
Ez csak tapasztalat, de sokkal rosszabb a helyzet. Ránézésre elég dilettáns áramkör. Az adatlapon előírt értékek, határértékek, alapvető tervezési előírások nincsenek betartva. Csoda hogy egyáltalán működik!
Fogadjunk, találok benne 20 hibát!
A FET-et cserélek bipolárisra döbbentett meg hirtelen. - Ezek szerint nem a felületszerelt verziót használod.
A további szomorú dolog, hogy ezek az amatőr áramkörök mind az ősrégi processzorokat használják. Nézegettem az ebay kínálatát, jellemzően az ilyen kapcsolásokban levő processzorokat árulják. Amit használok a pic18f24(5)k50 az majdnem pont olyan, mint a 2550. Csak nem kell hozzá kvarc, egy-két funkciót sokkal kényelmesebben lehet használni ÉS feleannyiba kerül.

A coff/elf kérdéshez még nem nőttem fel. ;)
De ha a makrókba ásod bele magad, akkor igazán elkészíthetnéd a rept/irp/irpc direktívákat. Bár nem egy nagy durranás egyik sem, de asm-ben igen használható dolgok. No, meg végre érezhetném hogy nem C-ben programozok. ;)

Ezek szerint nem a felületszerelt verziót használod.
Nem tudtam volna beforrasztani az alkatrészeket, másrészt pedig a panelt sem tudtam volna elkészíteni. Az akkori munkahelyemen volt egy CNC maró. Egy PC vezérelte. A főnökömmel kínlódtunk párszor a vasalásos panelkészítéssel és borongtunk a szarul sikerült panelek fölött. Akkor jött az ötlet hogy van neki egy régi koordináta asztala amit egy i8080 CPU vezérelt és ezt kéne átalakítani. (Ezt is a Videotontól vette.) Lettek erősebb léptetőmotorok, stb. A lényeg hogy ezzel csináltunk paneleket, persze csak egy oldalasakat lehetett. (Ehhez járult néha egy csomó huzalozott átkötés.) Mindez azért mert a mi zsebünkhöz mérve nagyon drágák voltak a panel gyártó cégek. Ez a helyzet pedig azt eredményezte hogy csak furatszerelt alkatrészek jöhettek szóba. Évtizedekkel ez előtt tussal rajzoltam kézzel és aggódtam hogy a vas-klorid oldat le ne áztassa a rajzolatot. Már jópár éve nem készítettem semmit sem. Itthon csak a maratásos megoldás jöhetne szóba, de nehezen szánnám rá magamat és már csinálni sincs mit. Nem nagyon hiányzik. Talán kifogytam az energiából, vagy a fene tudja.

Konklúzió: 8080-nal még mindent meg lehetett csinálni. ;)
Ez azért nem semmi! Maróval nyomtatott áramkört.
Utoljára több mint 30 éve vaskloridoztam, aztán áttértem a forrasztásra. Akkoriban még gyártottak wire-wrap technológiával. Az ehhez való huzallal, csupa szemes panelon jól lehet szerelni, csak speciális szerszám kell a csupaszoláshoz. A teflon szigetelésen minden elcsúzik, viszont nem olvad le forrasztáskor. Tehát méretre vágni, csupaszolni, hegyes csipesszel kis szemet hajlítani a végére és máris lehet forrasztani. Fiatal koromban még összekötöttem 16db 28 lábú tokot is, úgy szépen buszba.

Mostanában nincs idő prototípust építeni. Az áramkört megtervezem, és leadom a rajzot nyáktervezésre. Közben a kritikus részeket újraszámolom, szimulálom és esetleg az utolsó pillanatban még módosítok rajta. Amíg a nyákot gyártják, addigra beérkeznek az anyagok. Az első 2-3 példányt kézzel szerelem (a prototípus + a szoftveres kollégának). Ha már működik, akkor profi felületszerelő cég szereli a többit - mivel kisebb sorozatokról van szó, gyakorlatilag ők is kézzel ültetik, csak van kemencéjük. Kedvencem a 1206 méretű hálóellenállás.

No, de miből találtam ki a nem felületszerelt verziót? A két áramkör eltérő FET-eket tartalmaz. Lábasjószágban nem igazán lehet megfelelő típust kapni. A BS250 nem nyit ki teljesen, ez okozhatja a nagy feszültségesést. Ráadásul a felületszerelt verzióban levő FET sem lenne jó 3,3V esetén.
Ez a kisebbik probléma.
A további tervezési bakik, de nem az összes:
- A Pump1 és Pump2 induláskor túllépi a megadott max. 25mA/pin és valószínűleg a "Maximum current out of VSS pin" 300mA határértéket. Az utóbbi csak valószínű, mert az 1uF soros ellenállása néhány Ohm, míg a felületszerelten MLCC-t látok, azé meg néhány mOhm(!). (Ez van, amikor egy FET-et rányitsz az 5V-ra egy diódán és egy töltetlen kondenzátoron keresztül. Ezért kezdődnek az ilyen áramkörök egy ellenállással.)
- A Vpp maximális értéke terhelés nélkül <13V. Viszont pl. a pic18f2550 esetén az előírt 9..13,25V helyett, ha a terhelés 10mA "szeretne lenni"(adatlap D113 érték), akkor <3V. (Ez van, ha egy tápegységgel sorbakötsz 1kOhm ellenállást.) A valóságban nem ez a munkapont fog beállni, de minden bizonnyal a Vpp előírt minimális 9V-os értékét nem éri el.
- Közben az 5V-on 0,5..1,5V körüli negatív tüskék keletkeznek. Ez kiválóan nyomja a zavarokat az usb kábelre is.
Ezeket nem csak úgy kitaláltam, hanem szimulátorba ellenőriztem, ami Ohm törvényével és némi olvasgatással is helyettesíthető.

Ez egy amatőr áramkör, az esetek túlnyomó részében működik. Ha meg nem, akkor jön a tapasztalt szakértőkből álló fórumozás. :) Ilyen megoldásokat egy normális termékben nem szabad alkalmazni, bár egy-két kínai áramkör számomra is tudott új ismereteket nyújtani. :D

Korrekció: Kicsit változtatva a szimulációs paramétereken, talán a 300mA túllépése és a tápfeszültség zavara nem súlyos. A többi marad.

Az offtopic átirányítva innen.

Ezért:
IRP "See FOR."
IRPC "See FORC."
REPT "See REPEAT."

Mi a francnak erőltessem az elavult elnevezést? Egyébként még nincsenek kőbe vésve a nevek, csak nem akartam visszafelé menni az időben. Az új nevekről szerintem ránézésre jobban lehet érteni hogy mit is művelhetnek. Az irp nekem nem mond semmit, a for viszont igen.

Hát, ezt azzal indokolnám: Mert mást jelent.
A FOR: for VAR in LIST - legalábbis junikszos shell szintaksz szerint.
Annyiban igazad van, hogy elvileg ugyanaz. (De sajnálatos módon a MPASM és gpasm is a C szintax elemeit is belekeveri az asm leírásába. Ez azt eredményezi, hogy az inkább céül tudóknak látszólag könnyebb leírni valamit. Eközben meg hatalmas funkcióvesztés lép fel a valódi asm fordítókhoz képest.)

De mi a lényeg: Amíg a FOR egy kódrészlet ismételt végrehajtását jelenti, addig a REPT egy kódrészlet ismételt beillesztését jelenti - a lista elemeivel.

További side effectként a listavezérlés hatása is más - kellene legyen - a két direktívára. Csak az a baj, hogy a "modern" fordítók már ezt a funkcionalitást is elvesztették. Ezt láthatod a makróba ágyazott WHILE esetén is. A WHILE nem értelmezi az noexpand-ot. Kellene a LALL/SALL/XALL makró listavezérlés.

Egy rendes asm fordítónál a listavezérlés egy "párhuzamos réteg", amit szinte programozni lehet. Hatására a lista kinézete olyan lesz amilyet szeretnék.

A makrókról elég jó összefoglalót és példákat találhatsz pl. itt. Külön figyelmedbe ajánlom az IF1 és IF2 direktívákat! Ha rákeresel látni fogod, hogy elég sok helyen használják ezeket a direktívákat. Igaz, FORC is található. De azok nem olvasták ezt a commentet. ;)

Tegnapi döbbenetemben megfeledkeztem a lényegről! A konkatenálás hiányában (a #v() mint mackósajtban a brummogás) nem lesz igazán használható.

IRPC   Reg, LHU
      xorwf   Timer&Reg&, w
ENDM

Nem bánom, legyenek az eredeti nevek. Egyébként darázsfészekbe nyúltam ezzel a direktíva/makró bővítéssel. Lehet hogy rosszul látom, de olyan gány megoldásnak tűnik az egésznek a megvalósítása. Kénytelen vagyok telerakni printf() utasításokkal hogy valamennyire lássam, melyik kódrészlet mikor dolgozik. Össze-vissza vannak szétszórva az eljárások a különféle modulok között. Próbáltam már rendet vágni köztük, de rendszeresen elvesztem a fonalat és elmegy a kedvem az egésztől. Egyszerűen nem látom át az egészet. A linkelés alatti kód optimalizálás megírása egészen jól ment mert azt az egészet én találtam ki. Bár az egyszerűbbnek tűnik mint a makrók dolga.

No, írok ide valamit, nehogy elaluggy! ;)
(Ha megsértődsz, akkor megérdemled. ;))

Így kívülállóként úgy gondolom, hogy ezek a makrók egyszerűek: csak be kell helyettesíteni a kódot. Tehát ugyanolyannak kellene lennie, mint a while ciklus. A gond akkor kezdődik, ha nested.
Egy kis példa (CPU=LE):

mkDescriptor	macro	label, type, name
	local	Length = 1

	irpc	C, name
Length	=	Length+1
	endm

&label&Descriptor
		dw			2*Length, type
		irpc		C, name
		dw			'&C', 0
		endm
;
		mkDescriptor	Product, USB_STRING_DESCRIPTOR_TYPE, PName
;
ProductDescriptor
		dw		.12, USB_STRING_DESCRIPTOR_TYPE
		dw		'P', 0
		dw		'N', 0
		dw		'a', 0
		dw		'm', 0
		dw		'e', 0

A gond akkor kezdődik, ha nested.

Pontosan ezen akadtam el. Önmagában működött az irp, és akkor is ha többet egymásba ágyaztam. De ha a beágyazásba bekerült egy másik fajta - irpc, rept, while - akkor meghülyült a fordító. Egy verem szerű nyilvántartás kell neki hogy ne kavarodjon össze. Ahhoz viszont elég rendesen bele kell nyúlni a kódba. (Eddig - a lényegi működésüket tekintve - nem nyúltam azokhoz a részekhez amik a makrókkal foglalkoznak.) Néha amikor a kevés időm engedi akkor nekifogok és írkálom lefelé hogy mi mikor és mit hív meg a gpasm belsejében. Így tisztulgat a kép. Persze ha csak ezzel kéne foglalkoznom akkor már kész volna. Ez van.

De legalább előkerültél! :)
Ez a probléma nem újkeletű. Annak idején írtam egy wyse60 terminált, a billentyűzetet "néhány egyszerű makróval" ábrázolva. Ahhoz, hogy a tasm le tudja fordítani sem az EMS, sem az XMS nem volt elég. Helyette az alap memóriát kellett valami extrém 640->960kB méretűre növelni. Valószínűleg pont ezeket a pointerteket tárolták ott.
Ebben a fordítóban valószínűleg a while is ezért van maximálva.

Mostanában én is egy kicsit zűrzavaros vagyok. Úgy 2 hét múlva talán tudok tesztelgetni, ha ezzel tudok segíteni.

Viszont van egy rossz hírem! Át kellett rendezni az egyik programot és kétszer kellett nekifutni. Az első sikertelenséget az access ellenőrzés hibája okozta. Amint lesz rá időm, rakom ide a teszt kódot. (Vagy ideírom, hogy tévedtem. ;))

Értem én, hogy nyaljuk körbe a felhasználót fejlesztőt, meg milyen kényelmes, hogy macro assembler, meg akkor legyenek már rekurziók is a fordítás menetében, de nem túlzás ez egy cseppet? Elvégre assembly-ről beszélünk, ezt a nyelvet azért választja valaki, mert hardware közelében akar, szeret, tud programozni, s nem nyelvi absztrakciókra vágyik. Akkor írjon programot PIC-re awk-ban mondjuk. :) Vagy javascriptben. :) Viszont azzal fáradozni, hogy egy assembler efféle dolgokat is tudjon, cserébe fel kell forgatni az egész fordító kódját, eléggé a sajtreszelővel történő magányos örömszerzés gondolatát juttatja eszembe. Minek? Kerékpározzál inkább ki a természetbe feleséggel, barátnővel, egyetek pogácsát, igyatok meg egy-egy doboz sört, és hallgassátok a madarakat inkább. ;) Mondom ezt úgy, hogy használom a Gputils csomagot, s annak csak örülök, ha jobb.

tr '[:lower:]' '[:upper:]' <<<locsemege
LOCSEMEGE

A kerékpározós mondattal egyetértek.
Vajon miért ellenzed, hogy egy GNU projekt már akár a 70-es évek színvonalát a béka segge irányából, - de ahhoz nagyon közel - majdnem elérje?
4fonya barátunknak tényleg csak két problémája van ezzel a fejlesztéssel: kevés az ideje és más írta a nem is biztosan tökéletes kódot, amiben turkálnia kell. Innentől kezdve - bár nem így értetted - nem is biztos, hogy egy macro preprocesszor marhaság lenne.

Ellenzi a fene, csak az élet ennél értékesebb. Bátorkodom megjegyezni, szerintem ha nem egy erre tervezett kódba próbálna beleerőszakolni újabb feature-öket nyakatekert módon, hanem újra tervezné, majd írná az egészet, lehet, hamarabb készen lenne, ráadásul átláthatóbban, bővíthetően.

Különben is a makro a lusták játékszere. Nem állítom, hogy sohasem írtam le banksel, vagy valami hasonló nevűt, de van benne valami undorító, mert nem látja az ember, mi van ott.

tr '[:lower:]' '[:upper:]' <<<locsemege
LOCSEMEGE

mert nem látja az ember, mi van ott
No, ugye.
Pont ezért kellett az assume direktíva, hogy ne kelljen banksel-t írnod, hogy tájékoztasd a fordítót arról, hogy az egyébként is BSR-ben levő érték érvényes. Ráadásul kódot sem generál. A harmadik előnye, hogy áttekinthetőbbé teszi a kódot.

Ha most megtekintenéd a példa kódot kicsit feljebb, akkor beláthatod:
- Kicsit hosszabb PName esetén nem öröm beverni egy egész oldal "dw bötű,0" zagyvaságot, hogy egy stringet leírjál.
- Nem fogod eltéveszteni.
- Ha az egyszer jól megírt makró készen van, akkor egyetlen sorral tudsz usb decriptort definiálni.
- Ha csak ennyit látsz: "mkDescriptor Product, USB_STRING_DESCRIPTOR_TYPE, PName", akkor sokkal áttekinthetőbb a kód, mint egy oldalnyi dw esetén.

Rendesen megírt makrókkal könnyen olvasható kódot lehet előállítani akár kommentelés nélkül.

A Microchip fejlesztőitől kezdve, a sok kiváló C++ programozó soha nem dolgozott macro assemblerben. Valószínűleg Te sem, mert akkor nem kevernéd össze egy "gépelést könnyítő fícsörrel". Pedig a makró pont olyan feladtokat tud megoldani, amit a C makrókkal lehetetlen leírni. Próbálj meg elszakadni a rövidke, egy emberes hobbiprojekttől! Képzeld el, hogy egy nagyobb programot 5-6 ember tervez és programoz egyszerre. Gyakran volt olyan, hogy egyes algoritmusokhoz vagy matematikai leíráshoz értő kolléga tervezte a program egyes részeit. Majd kezébe adva a forrást, leelenőrizte a megvalósítást. Közben sem az adott processzorhoz, sem ahhoz az assemblerhez nem értett, komment meg alig volt. Csak elolvasta.

Ha egyszer a fejedben lakik a bitvadász (már pedig ezt tudjuk :), akkor egy műveletet jól meg tudsz fogalmazni az utasítások sorozatával. Erre rá lehet húzni még az algoritmust, folyamatábrát és kicsit cifrázni. Ekkor már régen nem a gépies behelyettesítést végzi a marózás. A végeredmény olyasmi, mit a yacc, csak még flexibilisebb.

De az igazi bézbólütő: Te sem C-ben programozol, pedig biztosan úgy is le tudnád írni ugyanazt. :-D

Csak kiragadva néhány dolgot, szép az idő, nem írok hosszan. ;) Valóban nem foglalkozom lehetőség szerint makrókkal. Egy esetben használtam: volt olyan, amikor a gputils az adott processzor összes utasítását nem ismerte. Ezeket megírtam makróként, a definíciós részben az operandus maszkolása, shiftelése egy-két db-ben, aztán a kódot lehettett írni, mintha mi sem történt volna. Bár valami sed-del történő előfeldolgozásra is szükségem volt, ne kérdezd, hogy miért.

Azért írok assembly-ben C helyett, mert a PIC nagyon picike kontroller. Pici a core, az utasításkészlet, kevés a memóriája, legyen az adat illetve programtár. Ilyen környezetben szeretek mindent kézben tartani. Ráadásul assembly-ben lelkiismeret-furdalás nélkül megteszem azt, hogy két 6 bites változót egy-egy byte alsó 6 bitjén tárolok, míg egy 4 bites változót ugyanezen két byte fennmaradó felső 2-2 bitjén. Mondhatod, hogy megszálottság, de pókerarccal megcsinálom, viszont C-ben ez némileg fájdalmasabb volna. (Az USB-s projectem assembly kódjában láthatsz rá példát. ;) )

tr '[:lower:]' '[:upper:]' <<<locsemege
LOCSEMEGE

"Ráadásul assembly-ben lelkiismeret-furdalás nélkül megteszem azt, hogy két 6 bites változót egy-egy byte alsó 6 bitjén tárolok, míg egy 4 bites változót ugyanezen két byte fennmaradó felső 2-2 bitjén. Mondhatod, hogy megszálottság, de pókerarccal megcsinálom, viszont C-ben ez némileg fájdalmasabb volna."
Egyreszt nem biztos, hogy mindig jol jarsz vele. (bar uC-ben sokszor a RAM a szuk keresztmetszet, flash-bol meg van eleg)

Masreszt:
ARM-on ugye 32 bites minden (ujabban van 64 bites is, de ez most mindegy). Nem szereti az architektura a nem 32 bitre align-olt dolgokat, bizonyos esetekben (pl. fuggvenyeknel - bar a Thumb meg van trukkozve) nincs is olyan, ami ne lenne 32 bites hataron. Ez azt jelenti, hogy a pointerek utolso 2 bitje mindig 0, ezt fel lehet hasznalni adattarolasra. Csak ha pointerkent akarod hasznalni, le kell maszkolni az utolso 2 bitet. Fejlesztettem mar olyan programot, amiben ez a lehetoseg ki volt hasznalva (bar ezen a bitvadaszos reszen nem turtam semmit). Egyebkent a kod jelentos resze C++-ban van. (meg van Lua, C, es Java is)

--
A strange game. The only winning move is not to play. How about a nice game of chess? - Wargames

Csak arra akartam kilyukadni, hogy assembly-ben pici mikrokontrollerre szerintem hatékonyabb, átláthatóbb, kellemesebb programozni, mint C-ben. Kedvencem - amire lehet, hogy van megoldás, csak én nem tudok róla -, amikor egy osztás hányadosára és maradékára is szükség van. Fogalmam sincs, hogyan érem el C-ben, hogy ne végezze el az osztást kétszer.

tr '[:lower:]' '[:upper:]' <<<locsemege
LOCSEMEGE

Csak kevered a szezont a fazonnal. :)
Tényleg kis méretű, 8 bites pic-ekről van szó, ahol minden "file" szervezésű. Gyakorlatilag csak 1db W munkaregiszter van. Az esetek többségében a file (==1 bájt ram) egyenrangú a W regiszterrel és a művelet eredményének tárolását meghatározhatod: W/f. A flash "teljesen Harward", esetleg típusonként eltérő módszerrel olvashatod. Az utasítás szélessége kisebb/nagyobb/még nagyobb típusoknál 12/14/16 bit, míg az adat 8 bit.
A gputils már a 16 biteseket sem kezeli, mert ott már W regiszter tömb van, a flash meg 24 bites, emiatt 2-3 féle map szerint olvashatod. A 32bites meg más gyártótól származó core-t tartalmaz.
Amiről írsz, az meg - régiesen szólva Motorola 68000 szerű - sok regiszteres, minimum 32/64 bites processzor. A sok regiszteres szervezés már a 8 bites ATMEL processzorokat is teljesen mássá teszi, miközben egyes műveletek csak regiszterben vagy bizonyos tartományon hajthatók végre.
Az utóbbiak a sok regiszter és a ramban megvalósított stack miatt kifejezetten alkalmasak magas szintű nyelvekhez, míg egy 8 bites pic esetén "még a stack is egy szoftver". :)

Bocsi, ez egy elnagyolt pongyola leírás. Csak feldobtam szavakat, hogy lássad teljesen másról van szó.

2-3 féle map szerint olvashatod

Jaj, ne is mondd, amikor ugyanazt a regisztert 3 különböző címen érhetem el. Direkt címzéssel, az operandusban 7 bites címrésszel, a többi pedig a BSR-ben, tehát lapozgatva. Aztán indirekt címzéssel az FSR-en keresztül ugyanazokon a címeken, mint direkt módon, de a bufferekben lyukak vannak, mert periodikusan megjelennek a speciális regiszterek (SFR-ek), ami persze direkt címzésnél szükségszerű. Aztán ugyancsak indirekt módon egy offsettel eltolva, de itt immáron folytonosak a bufferek, nem az eredeti címen vannak a regiszterek, s legalább kényelmesen kezelhetők.

Jó, ez a programozó kényelmét szolgálja, mert választhat, hogyan éri el ugyanazt a regisztert, akár néha így, néha úgy, de akkor is, hát na. :)

tr '[:lower:]' '[:upper:]' <<<locsemege
LOCSEMEGE

Ne keseregj. Szerinted mekkora a PIC mikrokontrolleres berendezéseket Linuxon fejlesztők, HUP-ot olvasók halmazának számossága? Mindez úgy, hogy az Mplab IDE megy Linuxon is. Magam azért szeretem jobban a Gputils-t, mert egyfelől benne van a Fedora repókban, másfelől nyílt forrású. Nem szeretek repón kívülről telepíteni, csak ha nagyon muszáj.

tr '[:lower:]' '[:upper:]' <<<locsemege
LOCSEMEGE

Igaz, az egyik 64 bites ARM-os volt. ;)

Mit szólnál locsemege légből kapott ötletéhez: makró preprocesszor? (Nem szégyen az.)
Lehet tesztelni awk-ban, átírni C-be, majd C++-ba. (A 70-es években assemblerben írták.)
Esetleg tudok benne segíten, bár legaláb annyira érek rá, mint Te.