| OldComp.cz https://oldcomp.cz/ |
|
| ASM: Získání celého čísla (příkazem Input) https://oldcomp.cz/viewtopic.php?f=40&t=3265 |
Stránka 1 z 2 |
| Autor: | tomascz [ 30.10.2015, 14:11 ] |
| Předmět příspěvku: | ASM: Získání celého čísla (příkazem Input) |
Měl bych dotaz jak z assembleru dát uživateli možnost zadat celé číslo a toto číslo získat do registru. Zkoušel jsem různé možnosti, ale nedaří se. Proximácké "Assembler a ZXS" sice ukazuje možnost, ale přijde mi to příliš nafouknuté - nechce se mi to prosekávat. Ideální řešení by pro mě bylo požádat interpret Basicu o provedení příkazu Input <číslo> (což neumím) a podle nějakého flagu zjistit, jestli bylo zadáno číslo (např. 123), nebo "nečíslo" (např. "123AHOJ") - a samozřejmě potlačit výpis chybových hlášení. Dá se to nějak? |
|
| Autor: | Busy [ 30.10.2015, 14:24 ] |
| Předmět příspěvku: | Re: ASM: Získání celého čísla (příkazem Input) |
No jasne, da sa Kód: 2 8000 *a
3 8000 ;"# input 08" 4 8000 ;Rutinka "input" pre nacitanie celeho cisla 0-65535 5 8000 6 8000 ;Pozor !!! Vola romku a potrebuje systemove premenne basicu !!! 7 8000 8 8000 ;Pri tomto priklade by vam velmi pomohol nejaky komentovany 9 8000 ;vypis romky, kde by ste sa o niektorych rutinkach mohli 10 8000 ;dozvediet viac, nez je v tychto strucnych komentaroch... 11 8000 12 8000 org #8000 13 8000 Maly priklad, ako INPUT pouzit: 14 8000 fd213a5c p ld iy,iy iy=#5c3a (nutne koli CLS) 15 8004 cd6b0d call #0d6b toto je basicove CLS 16 8007 cd1c80 loop call input volanie INPUTu 17 800a 3c inc a ak nastala nejaka chyba... 18 800b c0 ret nz ...tak tento priklad skonci 19 800c cd2b2d call #2d2b ulozene cisla v BC na zasobnik 20 800f 3e02 ld a,#02 otvorenie kanala #2 - kanala 'S' 21 8011 cd0116 call #1601 (pre vypis cisla) 22 8014 cde32d call #2de3 vypis obsahu zasobnika 23 8017 3e0d ld a,#0d vypis znaku 13 (aby dalsie cisla 24 8019 d7 rst #10 pisalo na dalsi riadok) 25 801a 18eb jr loop a opakuj slucku znovu. 26 801c 27 801c z 28 801c fd213a5c input ld iy,iy Vystup: 29 8020 fd3600ff ld (iy+#00),#ff 30 8024 fb ei a = kod chyby (#ff=bez chyby) 31 8025 2a3d5c ld hl,(errsp) bc = zadana hodnota ak a=#ff 32 8028 e5 push hl 33 8029 2a5d5c ld hl,(chadd) Vie citat lubovolny 34 802c e5 push hl v basicu pripustny vyraz 35 802d cd4480 call read ciselneho typu 0..65535 36 8030 e1 pop hl 37 8031 225d5c ld (chadd),hl Pozor !!! 38 8034 e1 pop hl Musi existovat Basic-system ! 39 8035 223d5c ld (errsp),hl (neznicene systemove premenne) 40 8038 fdcb01fe set 7,(iy+#01) 41 803c fd7e00 ld a,(iy+#00) 42 803f fd3600ff ld (iy+#00),#ff 43 8043 c9 ret 44 8044 Komentare: 45 8044 46 8044 ed733d5c read ld (errsp),sp Vektor navratu pri chybe 47 8048 fdcb0196 res 2,(iy+#01) Znacky: input line 48 804c fdcb01fe set 7,(iy+#01) beh programu 49 8050 fdcb37ee set 5,(iy+#37) input mode 50 8054 af xor a kanal K 51 8055 cd0116 call #1601 a jeho aktivacia 52 8058 cdbf16 call #16bf zmazanie pracovnej zony 53 805b 010100 ld bc,#01 Vyhradenie 1 bajtu 54 805e f7 rst #30 v pracovnej zone 55 805f 360d ld (hl),#0d pre koncovy enter 56 8061 225b5c ld (kcur),hl kurzor na zaciatok zony 57 8064 cd2c0f call #0f2c samotne volanie editora do romky 58 8067 fd362200 ld (iy+#22),#00 odoslanie kurzora do aleluja 59 806b cd1d11 call #111d vypis zony (teraz bez kurzora) 60 806e 2a615c ld hl,(worksp) ukazovatel na zaciatok 61 8071 225d5c ld (chadd),hl zadaneho retazca (nieco ako PC) 62 8074 e5 push hl 63 8075 fdcb01be res 7,(iy+#01) najprv skontrolujeme syntax 64 8079 cdfb24 call #24fb 1.vypocet (iba test syntaxe) 65 807c df rst #18 Za vyrazom musi 66 807d fe0d cp #0d nasledovat enter 67 807f c28a1c jp nz,#1c8a inak chyba 68 8082 e1 pop hl 69 8083 225d5c ld (chadd),hl Teraz pride 70 8086 fdcb01fe set 7,(iy+#01) skutocny vypocet 71 808a cdfb24 call #24fb 2.vypocet (uz naostro) 72 808d fdcb0176 bit 6,(iy+#01) Akeho typu je vysledok ? 73 8091 ca8a1c jp z,#1c8a ak retazec tak chyba 74 8094 c3991e jp #1e99 ak cislo tak ho dame do BC 75 8097 k 76 8097 l = k-z l = dlzka INPUT rutinky 77 8097 78 8097 iy = #5c3a definicie niektorych pouzitych 79 8097 errnr = #5c3a adries a systemovych premennych 80 8097 errsp = #5c3d 81 8097 kcur = #5c5b 82 8097 chadd = #5c5d 83 8097 worksp = #5c61 84 8097 stkbot = #5c63 chadd 5c5d * errnr 5c3a * errsp 5c3d * input 801c * iy 5c3a * k 8097 * kcur 5c5b * l 007b * loop 8007 * p 8000 * read 8044 * stkbot 5c63 * worksp 5c61 * z 801c * errors:0 |
|
| Autor: | tomascz [ 30.10.2015, 14:56 ] |
| Předmět příspěvku: | Re: ASM: Získání celého čísla (příkazem Input) |
To si deláš srandu!! Velice díky, zkusím za chvilinku. |
|
| Autor: | tomascz [ 30.10.2015, 18:53 ] |
| Předmět příspěvku: | Re: ASM: Získání celého čísla (příkazem Input) |
No, nakonec i tvoje řešení bylo moc nafouknuté, takže jsem zased a zkusil si to napsat sám. Můj přístup má hodně omezení, která zde nebudu rozebírat, ale vím o nich. Zatím to není dokončeno (zbývají detaily) a vpodstatě není problém - až na jeden: Napíšu číslo 1234; jednou zmáčku Backspace (CS+0), vše je ok; podruhé zmáčknu Backspace a ejhle - kurzor se mi přelije na druhou řádku. Co s tím? Kód: (1 - ok) Zadej cislo: 1234< (2 - ok) Zadej cislo: 123< (3 - spatne, viz kurzor na nove radce) Zadej cislo: 123 < OC trochu prasí tabelátory, takže formátování mírně rozhozeno. Kód: DF_CC .EQU $5c84
S_POSN .EQU $5c88 ReadNum ; precte cele kladne cislo do HL; C = max pocet znaku * ld hl,S_POSN ; reset citace zbyvajiciho mista na radce * ld (hl),0 ld hl,DF_CC ; do HL aktualni pozice kurzoru _RdNum ld a,'<' ; kresba kurzoru rst 10 call PAUSE_1 ; cekani na stisk klavesy ld a,(LASTKEY) dec (hl) ; znak vykreslen na misto kurzoru cp 13 ; test zda znak Enter jr z,_atoi cp 12 ; test zda znak Backspace jr z,_RdBack cp '0' ; test zda znak v {0..9} jr c,_RdNum cp '9'+1 jr nc,_RdNum rst 10 jr _RdNum _RdBack ld a,' ' rst 10 dec (hl) dec (hl) jr _RdNum _atoi ret ; TODO |
|
| Autor: | tomascz [ 30.10.2015, 19:37 ] |
| Předmět příspěvku: | Re: ASM: Získání celého čísla (příkazem Input) |
No, tak nějak dáno dohromady, i když nevím, co přesně jsem vlastně udělal Pokud S_POSN znamená něco jiného nebo pokud existuje lepší řešení, rád bych se ho dozvěděl |
|
| Autor: | Busy [ 30.10.2015, 20:03 ] |
| Předmět příspěvku: | Re: ASM: Získání celého čísla (příkazem Input) |
No ale toto tvoje riesenie neposkytuje cely komfort editora riadku v romke zavolany pre editaciu riadku v prikaze INPUT. Nemozes sa kurzorovymi klavesami prechadzat po cisle a opravovat znaky niekde uprostred alebo na zaciatku, nemozes napisat vyraz ako napr. 123+456... tomascz píše: Pokud S_POSN znamená něco jiného nebo pokud existuje lepší řešení, rád bych se ho dozvěděl Systemky ako S_POSN ci DF_CC nepouzivaj, nie je to s nimi tak jednoduche. Namiesto toho, vzdy po stlaceni kazdej klavesy, vypis normalny PRINT AT (kody 22,stlpec,riadok) a potom vypis vzdy cely zadany riadok aj s kurzorom na konci a v pripade ze klavesa bola DELETE tak vypis este jednu medzeru. A vobec sa nemusis starat o pozicie vypisu alebo ci ti nahodou nepretecie na dalsi riadok.
|
|
| Autor: | tomascz [ 30.10.2015, 20:20 ] |
| Předmět příspěvku: | Re: ASM: Získání celého čísla (příkazem Input) |
Busy píše: No ale toto tvoje riesenie neposkytuje cely komfort editora riadku v romke zavolany pre editaciu riadku v prikaze INPUT. Nemozes sa kurzorovymi klavesami prechadzat po cisle a opravovat znaky niekde uprostred alebo na zaciatku, nemozes napisat vyraz ako napr. 123+456... Volné procházení čísla kurzorem ani vyhodnocování výrazů nepotřebuju - můj původní dotaz byl, jestli existuje rutina, která by dokázala přečíst číselný "řetězec", parsovat ho a vrátit číselnou podobu v nějakém registru (možná jsem to měl už předtím formulovat líp). Busy píše: tomascz píše: Pokud S_POSN znamená něco jiného nebo pokud existuje lepší řešení, rád bych se ho dozvěděl Systemky ako S_POSN ci DF_CC nepouzivaj, nie je to s nimi tak jednoduche. Namiesto toho, vzdy po stlaceni kazdej klavesy, vypis normalny PRINT AT (kody 22,stlpec,riadok) a potom vypis vzdy cely zadany riadok aj s kurzorom na konci a v pripade ze klavesa bola DELETE tak vypis este jednu medzeru. A vobec sa nemusis starat o pozicie vypisu alebo ci ti nahodou nepretecie na dalsi riadok.Zatím se to zdá být uspokojivé řešení. Nechci využívat žádný pomocný buffer kde bych uchovával dosavadní řetězec. Místo toho obrazovku používám jako buffer onoho číselného "řetězce" a ovlivňuju jenom poslední napsaný znak a kurzor (takže v _atoi budu sahat přímo na to, co je na obrazovce, abych v HL vyrobil číselnou podobu). Ještě omezuju počet cifer zadávaného čísla (třeba tříciferné číslo) - tím bych snad mohl tu neblbuvzdornost aspoň trochu oddálit... |
|
| Autor: | Busy [ 31.10.2015, 00:47 ] |
| Předmět příspěvku: | Re: ASM: Získání celého čísla (příkazem Input) |
tomascz píše: můj původní dotaz byl, jestli existuje rutina, která by dokázala přečíst číselný "řetězec", parsovat ho a vrátit číselnou podobu v nějakém registru (možná jsem to měl už předtím formulovat líp). Aj take existuje - funkcia VAL v romke - to je vlastne take pekne "_atoi" Kód: atoi ld hl,#00 Vstup: DE = zaciatok retazca cislicloop ld a,(de) cp '9'+1 ret nc sub '0' ret c add hl,hl ld b,h ld c,l add hl,hl add hl,hl add hl,bc ld c,a ld b,0 add hl,bc inc de jr loop Vystup: HL = hodnota cisla tomascz píše: Zatím se to zdá být uspokojivé řešení. Nechci využívat žádný pomocný buffer kde bych uchovával dosavadní řetězec. Místo toho obrazovku používám jako buffer onoho číselného "řetězce" a ovlivňuju jenom poslední napsaný znak a kurzor (takže v _atoi budu sahat přímo na to, co je na obrazovce, abych v HL vyrobil číselnou podobu). Takze ak tomu spravne rozumiem, tak namiesto jednoducheho buffera chces radsej komplikovane volat funkciu SCREEN$ v romke ? Alebo namiesto komplikovaneho volania romky si potrebne OCR urobis (este komplikovanejsie) vlastnou rutinkou ? |
|
| Autor: | tomascz [ 31.10.2015, 01:56 ] | ||
| Předmět příspěvku: | Re: ASM: Získání celého čísla (příkazem Input) | ||
Busy píše: tomascz píše: můj původní dotaz byl, jestli existuje rutina, která by dokázala přečíst číselný "řetězec", parsovat ho a vrátit číselnou podobu v nějakém registru (možná jsem to měl už předtím formulovat líp). Aj take existuje - funkcia VAL v romke - to je vlastne take pekne "_atoi" HL := (8+2)*HL To je vyčuraný, to je velmi vyčuraný Busy píše: tomascz píše: Zatím se to zdá být uspokojivé řešení. Nechci využívat žádný pomocný buffer kde bych uchovával dosavadní řetězec. Místo toho obrazovku používám jako buffer onoho číselného "řetězce" a ovlivňuju jenom poslední napsaný znak a kurzor (takže v _atoi budu sahat přímo na to, co je na obrazovce, abych v HL vyrobil číselnou podobu). Takze ak tomu spravne rozumiem, tak namiesto jednoducheho buffera chces radsej komplikovane volat funkciu SCREEN$ v romke ? Alebo namiesto komplikovaneho volania romky si potrebne OCR urobis (este komplikovanejsie) vlastnou rutinkou ? Nn, protože volat Basic z assembleru neumim Btw, jak bys to tedy napsal s tím Val? Nějak totálně minimalistickej přístup (co do počtu bajtů). EDIT: Když v Basicu napíšu, 10 LET A=0, 20 INPUT A, tak výsledek má odhadem 30 bajtů, možná míň, neumím číst ten "bajtkód" v TAPce. Bylo by možný tu velikost nějak zdrcnout i v assembleru?
|
|||
| Autor: | Busy [ 31.10.2015, 11:47 ] |
| Předmět příspěvku: | Re: ASM: Získání celého čísla (příkazem Input) |
tomascz píše: Nejprv jsem kód znaku ukládal do nultého mikrořádku nad tisknutým číslem, ale to vypadalo blbě. Co je krasna ukazka pouzitia bufferu tomascz píše: Tak jsem to obešel strkáním mezivýsledku do zásobníku: (1) ke stávajícímu řetězci "123" přibyde znak "4" - stávající hodnotu 123 strčím do zásobníku a novou určím jako 1234; (2) ke stávajícímu řetězci "123" přibyde znak "Backspace" - nová hodnota je popnuta ze zásobníku. Viz příloha, ať se zasměješ Dalsia krasna ukazka pouzita bufferu, akurat ten buffer adresujes registrom SP tomascz píše: Btw, jak bys to tedy napsal s tím Val? Nějak totálně minimalistickej přístup (co do počtu bajtů). Rutinka pre VAL je v romke na adrese #35DE, pred zavolanim treba dat do systemovej premennej #5C5D zaciatok retazcoveho vyrazu nasledujuceho za VAL (napr. cislo v uvodzovkach). Alebo zavolat VAL o tri bajty dalej s adresou vyrazu v HL. Vysledok je ciselna hodnota ulozena na zasobniku kalkulacky. Hodnotu treba od tial prevziat, napr. rutinkou #1E99 ktora ju vrati v registri BC. Ale ako tak na to pozeram, "rucny" prevod postupnosti cislic na hodnotu co som uviedol vyssie, vychadza na menej bajtov. Takze pokial chces co najkratsi kod, a nepotrebujes velku univerzalnost a moznost pisat akekolvek vyrazy, VAL nie je vhodne riesenie.tomascz píše: EDIT: Když v Basicu napíšu, 10 LET A=0, 20 INPUT A, tak výsledek má odhadem 30 bajtů, možná míň, neumím číst ten "bajtkód" v TAPce. Bylo by možný tu velikost nějak zdrcnout i v assembleru? Naco tam je to LET A=0, ?Inak samotny INPUT a zabera presne dva bajty, prvy je kod prikazu INPUT a druhy je pismenko "a" Na pracu s TAP subormi existuje kopec utilitiek, staci zagooglit. Napriklad aj ja som autorom jednej takejto sady: http://busy.speccy.cz/download/taput104.rar Najdes tu rozne konvertory medzi roznymi formatmi (vratane cisteho binarneho suboru bez hlaviciek) ale aj rozne utilitky na vypis obsahu TAPky, vratane moznosti dekodovania basic programu do textovej formy. |
|
| Autor: | tomascz [ 31.10.2015, 23:01 ] | ||
| Předmět příspěvku: | Re: ASM: Získání celého čísla (příkazem Input) | ||
Busy píše: tomascz píše: Nejprv jsem kód znaku ukládal do nultého mikrořádku nad tisknutým číslem, ale to vypadalo blbě. Co je krasna ukazka pouzitia bufferu tomascz píše: Tak jsem to obešel strkáním mezivýsledku do zásobníku: (1) ke stávajícímu řetězci "123" přibyde znak "4" - stávající hodnotu 123 strčím do zásobníku a novou určím jako 1234; (2) ke stávajícímu řetězci "123" přibyde znak "Backspace" - nová hodnota je popnuta ze zásobníku. Viz příloha, ať se zasměješ Dalsia krasna ukazka pouzita bufferu, akurat ten buffer adresujes registrom SP Njn... Na druhou stranu to (v tento okamžik) nevyrábím proto, aby to bylo krásný a rychlý, ale pouze aby to fungovalo Busy píše: Rutinka pre VAL je v romke na adrese #35DE, pred zavolanim treba dat do systemovej premennej #5C5D zaciatok retazcoveho vyrazu nasledujuceho za VAL (napr. cislo v uvodzovkach). Alebo zavolat VAL o tri bajty dalej s adresou vyrazu v HL. Vysledok je ciselna hodnota ulozena na zasobniku kalkulacky. Hodnotu treba od tial prevziat, napr. rutinkou #1E99 ktora ju vrati v registri BC. Ale ako tak na to pozeram, "rucny" prevod postupnosti cislic na hodnotu co som uviedol vyssie, vychadza na menej bajtov. Takze pokial chces co najkratsi kod, a nepotrebujes velku univerzalnost a moznost pisat akekolvek vyrazy, VAL nie je vhodne riesenie. No, ZX ROM neznám, a proto jsem se konečně donutil si přečíst článek o kalkulátoru Spectra, který jsem si stáhnul někdy v roce 2010 a od té doby se mi jen válel na disku. Řešení přes Val se zdá naprosto ideální, už proto, že má jen cca deset bajtů Busy píše: tomascz píše: EDIT: Když v Basicu napíšu, 10 LET A=0, 20 INPUT A, tak výsledek má odhadem 30 bajtů, možná míň, neumím číst ten "bajtkód" v TAPce. Bylo by možný tu velikost nějak zdrcnout i v assembleru? Naco tam je to LET A=0, ?Já už skoro dvacet let nedělal v Basicu, takže mi přišlo celkem správné nejdřív alokovat a inicializovat místo pro proměnnou A a pak ji případně naplnit. EDIT: Při pročišťování programu jsem pročistil i řádek, který tam měl, takže reupnuto.
|
|||
| Autor: | Busy [ 01.11.2015, 20:00 ] |
| Předmět příspěvku: | Re: ASM: Získání celého čísla (příkazem Input) |
tomascz píše: No, ZX ROM neznám, a proto jsem se konečně donutil si přečíst článek o kalkulátoru Spectra, který jsem si stáhnul někdy v roce 2010 a od té doby se mi jen válel na disku. Ano, to je dalsia moznost ako vyuzit nejake vypoctove funkcie z romky.tomascz píše: Řešení přes Val se zdá naprosto ideální, už proto, že má jen cca deset bajtů Ten handler mas zle napisany. Pri chybe romka urobi v podstate toto: LD (IY+0),kod_chyby : LD SP,(ERR_SP) : RET. Tvoj CustErr sice chybu odchyti, ale nasledne SP nastavi na (v tej dobe uz nezmyselnu) hodnotu ulozenu v SP0. Lenze zasobnik je uz davno uplne mimo a vsetky navratove adresy su stratene, takze nasledne POPy nacitaju nezmysly a nasledny RET skoci niekam doblba. Skus pozriet aky error handler mam pouzity ja v tej mojej INPUT rutinke. Dolezite je toto:Kód: ld hl,(errsp) Odpametanie povodnej hodnoty error handlera push hl call read Zavolanie rutinky v ktorej maju byt odchytene chyby pop hl ld (errsp),hl Obnovenie povodnej hodnoty error handlera ld a,(iy+#00) Kod vzniknutej chyby alebo #FF=OK ret read ld (errsp),sp Definovanie noveho error handlera ... pokracovanie rutinky tomascz píše: Já už skoro dvacet let nedělal v Basicu, takže mi přišlo celkem správné nejdřív alokovat a inicializovat místo pro proměnnou A a pak ji případně naplnit. Nie je treba, prikaz INPUT si premennu vie naalokovat sam |
|
| Autor: | tomascz [ 02.11.2015, 02:49 ] | ||
| Předmět příspěvku: | Re: ASM: Získání celého čísla (příkazem Input) | ||
Busy píše: Kód: ld hl,(errsp) Odpametanie povodnej hodnoty error handlera push hl call read Zavolanie rutinky v ktorej maju byt odchytene chyby pop hl ld (errsp),hl Obnovenie povodnej hodnoty error handlera ld a,(iy+#00) Kod vzniknutej chyby alebo #FF=OK ret read ld (errsp),sp Definovanie noveho error handlera ... pokracovanie rutinky Díky, velice poučné. Jenom zas malá drobnost na kráse. Když chyba nenastane, program skončí klasicky "0 Ok, 0:1". Když chyba nastane a já ji ošetřím, skončí to hlášením "F ####N!-0:1" (což je skoro ono, resp. je to pokrok od "Nonsense in Basic") - viz opět příloha. Co s tím?
|
|||
| Autor: | Busy [ 02.11.2015, 15:20 ] |
| Předmět příspěvku: | Re: ASM: Získání celého čísla (příkazem Input) |
tomascz píše: skončí to hlášením "F ####N!-0:1" (což je skoro ono, resp. je to pokrok od "Nonsense in Basic") - viz opět příloha. Co s tím? Pred zavolanim tohto programu valerr treba v basicu urobit LET ahoj=0 : )
|
|
| Autor: | Busy [ 03.11.2015, 16:36 ] |
| Předmět příspěvku: | Re: ASM: Získání celého čísla (příkazem Input) |
No dobre, a teraz vazne. Pokial chces aby sa to po uspesne aktivovanom error handleri korektne vratilo z USR do basicu, je nutne pred navratom nastavit tienove HL na hodnotu #2758: Kód: ld a,255 ; aby Ok,0:1 Pokial to tak nespravis, funkcia USR sa z toho psychicky zosype... ld (iy+0),a ld hl,#2758 <= toto je nove exx <= toto je nove ret ; navrat do Basicu A este dva postrehy: Kód: ld a,255 ; aby Ok,0:1 Staci rovno napisat ld (iy+0),255ld (iy+0),a Kód: call FP_TO_BC ; do BC vysledek A tu zase staci rovno napisat jp FP_TO_BC
ret |
|
| Stránka 1 z 2 | Všechny časy jsou v UTC + 1 hodina [ Letní čas ] |
| Powered by phpBB® Forum Software © phpBB Group http://www.phpbb.com/ |
|