OldComp.cz

Komunitní diskuzní fórum pro fanoušky historických počítačů


Právě je 27.04.2024, 08:20

Všechny časy jsou v UTC + 1 hodina [ Letní čas ]




Odeslat nové téma Odpovědět na téma  [ Příspěvků: 598 ]  Přejít na stránku Předchozí  1, 2, 3, 4, 5 ... 40  Další
Autor Zpráva
 Předmět příspěvku: Re: Macro FORTH
PříspěvekNapsal: 14.05.2020, 14:10 
Offline
Óm Nejvyšší

Registrován: 22.05.2013, 21:14
Příspěvky: 3675
Bydliště: Bratislava
Has thanked: 373 times
Been thanked: 798 times
_dworkin píše:
Predpokladam ze si myslel asi
Kód:
konstanta   equ  hodnota  ;  nesmie sa menit
premenna     =   hodnota  ;  moze sa predefinovat na inu hodnotu
?
Jaaaaj, ano, samozrejme takto som to chcel napisat. Som slepy :)


Nahoru
 Profil  
 
 Předmět příspěvku: Re: Macro FORTH
PříspěvekNapsal: 14.05.2020, 16:02 
Offline
Pan Štábní

Registrován: 23.06.2013, 23:49
Příspěvky: 1120
Has thanked: 100 times
Been thanked: 161 times
A asi ani sjasmplus nepodporuje v predzpracovani zdrojaku neco co se chova jako zasobnik co? Kdo by taky chtel takovou silenost... :)

#createstack ZASOBNIK
#push(ZASOBNIK,"prvni")
#pop(ZASOBNIK)

Takze verze co zpracovava IF ELSE THEN
Kód:
define(IF_COUNT,100)dnl
dnl
define(NEWLABEL,`$1$2$3')dnl
dnl
define(IF,`
define(`IF_COUNT', incr(IF_COUNT))dnl
pushdef(`ELSE_STACK', IF_COUNT)dnl
pushdef(`THEN_STACK', IF_COUNT)dnl
    LD  A, H
    OR  L
    EX  DE, HL
    POP DE
    JP  z, NEWLABEL( else, IF_COUNT)')dnl
dnl
define(ELSE,`
    JP NEWLABEL( endif, THEN_STACK)
NEWLABEL( else, ELSE_STACK):popdef(`ELSE_STACK')')dnl
dnl
define(THEN,`
ifelse(ELSE_STACK, THEN_STACK,`NEWLABEL( else, ELSE_STACK)  EQU $    ; = endif
popdef(`ELSE_STACK')')NEWLABEL( endif, THEN_STACK):dnl
popdef(`THEN_STACK')')dnl
dnl

// ------
IF
; aaa
ELSE
    IF
        IF
            IF
; bbb
            THEN
        ELSE
            IF
; ccc
            THEN
        THEN
    THEN
THEN

Neobsahuje zadne makra, takze by to mohl z80asm zvladnout. Ale mozna je to stejne k nicemu protoze to tam muze narazit na instrukce typu "SUB H" a "SBC A, H", ktere jsem uz videl zapisovane jinak. Rozhodl jsem se ponechat pokazde navesti "endif" i kdyz je nepouzito, protoze tam neni zadne ELSE. Ale v budoucnu treba nekdo muze chtit mit neco jako "breakif". A pak by musel resit zda to konci na else nebo endif. Nejlepsi by bylo to vedet uz v IF.

Jo a nejsem si jisty zda se to ELSE ma chovat jak mam odsazene. Ze patri vzdy k aktualnimu tedy poslednimu neukoncenemu IF. Otestuji snad pozdeji.

PS: Ohlidat si v M4 aby ti nepribyvali prazdne radky nebo nechybeli je docela magie. Hrani si s dnl. U toho THEN jsem docela bojoval.
PSS: Ty makra v M4 jsou fakt uplne krypticky... nevidet to predtim tak jsem ztracen.

_________________
Z80 Forth compiler (ZX Spectrum 48kb): https://codeberg.org/DW0RKiN/M4_FORTH


Nahoru
 Profil  
 
 Předmět příspěvku: Re: Macro FORTH
PříspěvekNapsal: 14.05.2020, 16:19 
Offline
Pan Štábní

Registrován: 23.06.2013, 23:49
Příspěvky: 1120
Has thanked: 100 times
Been thanked: 161 times
Vlastne asi ten zasobnik jde nahradit pomoci toho Lua skriptu?

_________________
Z80 Forth compiler (ZX Spectrum 48kb): https://codeberg.org/DW0RKiN/M4_FORTH


Nahoru
 Profil  
 
 Předmět příspěvku: Re: Macro FORTH
PříspěvekNapsal: 14.05.2020, 22:17 
Offline
Pan Štábní

Registrován: 23.06.2013, 23:49
Příspěvky: 1120
Has thanked: 100 times
Been thanked: 161 times
Kubik píše:
Tak ja nevim, ale kde mas hodnotu indexu u DO cyklu? V normalnim FORTHu je v RAS (zasobnik navratovych adres), ale pokud resis cykly nejakym LUA skriptem, tak mi nejak nedochazi, kde bude pri behu programu ulozena ta hodnota...
Nebylo by v tomhle okamziku jednodussi proste FORTH pouzit jako FORTH, a nekomplikovat to makrama v nekolika programovacich jazycich? :) Pokud si totis napises tech par zakladnich slov ve strojaku, tak potom muzes program napsat pomerne jednoduse. Podivej se treba na CamelForth.



Co je to RAS? Aha to je jen zkratka z anglictiny pro Return A..? Stack.
Hodnota konce a indexu je na datovem zasobniku.
"stop index DO ... LOOP"
DO nacte index a stop z datoveho zasobniku (SP) a ulozi ho do zasobniku navratovych adres (HL') a definuje navesti pro opetovny skok
LOOP nacte index a stop ze zasobniku navratovych adres, inkremetuje (zvysi?) index, provede porovnani a rozhodne se zda ulozi aktualizovanou hodnotu nazpet a skoci na navesti v LOOP a nebo ukonci smycku.

Skript dela to, ze vymysli pro DO jednoznacny nazev navesti a ze ho rekne LOOP na ktere DO ma skakat, ke komu patri. Je to kompilovany a ne interpretovany a kompiluji to na na PC a ne ZX. Ale muzu se na CamelForth kouknout, zda to dokazi pochopit.

Plus teda skript nahradi slovo za sekvenci prikazu v assembleru samozrejme. Protoze vysledek m4 ma byt assembler.

PS: Ten kod pro DO je kousek nahore a prislo me ze to nepotrebuje vic komentaru... .)

Datovy zasobnik: HL, DE, (SP), (SP+2),(SP+4),...
Zasobnik navratovych adres: (HL'),(HL'+2),(HL'+4),(HL'+6),...

Prvne ulozi HL(index) a DE (stop) na zasobnik.
Prepne se na stinove registry
Nacte to postupne do DE' a pomoci HL' ulozi
Vrati se ze stinovych registru
Nacte do HL a DE nasledujici hodnoty co cekaji v zasobniku

Diky tomu ze je pevne dany co je HL,DE,HL' a ze si musim ohlidat co tam bude az skonci nejake funkce a ze vse ostatni je volne pro pouziti, ale s tim ze tam je v podstate nahodna hodnota (krome IX a IY na ktere jsem nesahal) muzu vytvaret tyhle funkce a skladat program z mensich celku. Je uplne jedno co je to za program, je to uplne univerzalni. Neni to samozrejme nejrychlejsi, ani nejkratsi. I kdyz ten FORTH by mohl byt kratsi nez "assembler". Ale to by musel byt tokenizovany jak basic. To by byl ale pomalejsi, i kdyz stale rychlejsi nez basic. A v necem by ho prekonaval. Ale taky fakt o dost tezsi na pochopeni.

_________________
Z80 Forth compiler (ZX Spectrum 48kb): https://codeberg.org/DW0RKiN/M4_FORTH


Nahoru
 Profil  
 
 Předmět příspěvku: Re: Macro FORTH
PříspěvekNapsal: 14.05.2020, 22:50 
Offline
Pan Štábní

Registrován: 23.06.2013, 23:49
Příspěvky: 1120
Has thanked: 100 times
Been thanked: 161 times
Aha ty mozna narazis na tu testovaci ukazku, kde tam nikde neukladam nic na zasobnik predtim. Protoze je to testovaci a je to jedno jak a co se to ulozi na zasobnik. V podstate to tam ani byt nemusi protoze je to FORTH a ma odeleny data, takze pri zavolani uz na tom zasobniku muze vse lezet.

_________________
Z80 Forth compiler (ZX Spectrum 48kb): https://codeberg.org/DW0RKiN/M4_FORTH


Nahoru
 Profil  
 
 Předmět příspěvku: Re: Macro FORTH
PříspěvekNapsal: 14.05.2020, 23:11 
Offline
Óm Nejvyšší
Uživatelský avatar

Registrován: 28.01.2016, 23:57
Příspěvky: 3756
Has thanked: 213 times
Been thanked: 388 times
Aha - ja se popravde receno nesnazil pochopit ty makra, protoze mi to prislo jako LISP :) Jeste tam semtam nekde napis "lambda" a bude to dokonale :)
FORTH je tokenizovany - teda podle toho, jakou zvolis implementaci, je nekolik zakladnich typu, ale vetsina je nejakym zpusobem tokenizovana.
Diky tomu muzes snadno psat slova primo v assembleru bez nejakych slozitych maker. Na podminky/cykly se pouzije navesti, a vsechno ostatni jsou tokeny. Token ve FORTHu je adresa toho ktereho slova. Takze napriklad (CamelForth):

;C MIN n1 n2 -- n3 signed minimum
; 2DUP > IF SWAP THEN DROP ;
head MIN,3,MIN,docolon
dw TWODUP,GREATER,qbranch,MIN1,SWOP
MIN1: dw DROP,EXIT

Prvni radek je komentar - definujeme slovo MIN, ktere ze dvou hodnot na zasobniku necha to mensi.
Druhy radek je opet komentar - takhle by to slovo bylo definovane primo ve FORTHu.
Treti radek - makro, generuje standardni hlavicku slova.
Ctvrty radek - tokeny pro "2DUP > IF SWAP". MIN1 je navesti, ktere rika, kam se ma skocit, pokud podminka neni splnena.
Paty radek - navesti, na ktere se skoci, pokud podminka nebyla splnena, a pak zbytek definice slova:" DROP ;"

Jedine makro je tam "head" - hlavicka slova ve FORTHu ma standardni format a byla by otrava to porad opisovat, takze proto makro. Zbytek jsou tokeny, presne tak, jak by je vygeneroval interpret.

Nebo jednodussi priklad:
DROP DROP ;
se zapise jako
dw DROP,DROP,EXIT

_________________
Nikdy nediskutujte s blbcem. Stáhne vás na svoji úroveň a vyhraje zkušeností.


Nahoru
 Profil  
 
 Předmět příspěvku: Re: Macro FORTH
PříspěvekNapsal: 22.05.2020, 13:42 
Offline
Pan Štábní

Registrován: 23.06.2013, 23:49
Příspěvky: 1120
Has thanked: 100 times
Been thanked: 161 times
Provedl jsem spoustu prace a behem toho se trosicku naucil znackovaci jazyk M4. Bylo toho uz fakt hodne tak jsem to dal na github: https://github.com/DW0RKiN/M4_FORTH

Kdyz vite co delate a provedete nejake optimalizace tak vysledek vypada fakt dobre.
Original:
Kód:
: fib1 ( n1 -- n2 )
    dup 2 < if drop 1 exit then
    dup  1- recursive
    swap 2- recursive  + ;
   
: fib1-bench 1000 0 do
    20 0 do i fib1 drop loop
  loop ;

fib1-bench

Optimalizovana varianta:
Kód:
include(`./FIRST.M4')dnl
    ORG 32768
    INIT(35000)
    SCALL(fib1_bench)
    STOP   
    SCOLON(fib1x,( a -- b ))
        DUP_PUSH_LT_IF(2) DROP_PUSH(1) SEXIT THEN
        DUP  ONE_SUB SCALL(fib1x)
        SWAP TWO_SUB SCALL(fib1x) ADD
    SSEMICOLON
    SCOLON(fib1_bench,( -- ))
        PUSH2(1000,0) SDO
            PUSH2(20,0) SDO SI SCALL(fib1x) DROP SLOOP
        SLOOP
    SSEMICOLON
include({./LAST.M4})dnl
Kde jsem nahradil
Citace:
DUP PUSH(2) LT IF
konstrukci, ktera porovna hodnotu zda je mensi nez dva a pokud ano provede IF za optimalizovanou DUP_PUSH_LT_IF(2). Protoze prvni neoptimalizovana varianta udela kopii porovnavane hodnoty na zasobnik, vlozi na zasobnik konstantu. Porovna hodnotu s konstantou a obe zrusi a misto toho vlozi na zasobnik vysledek. Nacte vysledek pres IF a vyhodnoti ho. Coz je hodne zbytecne prace na zasobniku na to ze chceme nedestruktivni
Citace:
IF (HL<2)
. Takze jsem vytvoril na tahle optimalizovane slova, protoze by se budou pouzivat casto. Nejsou teda dokonale, protoze pokud resime u HL znamenko tak nejlepsi reseni je
Kód:
LD B, H
LD C, L   ; BC = HL a BC muzeme volne pouzivat
DEC BC
DEC BC
RL B
JP nc, ELSE
, ale to by slo taky do toho slova pomoci M4 dodelat. To co M4 neumi je najit v souboru
Citace:
DUP PUSH(x)
a automaticky ho zmenit na
Citace:
DUP_PUSH(x)
, coz je dalsi optimalizovane slovo.
Podobne jednoduche optimalizace jsou PUSH2(1000,0) a DROP_PUSH(1).

Vetsi orisek je pouziti smycek ktere ukladaji sve hodnoty na obycejny datovy zasobnik. To uz musi programator videt ze na zacatku za DO a konci pred LOOP je pozice datoveho zasobniku stejna.

Dalsi orisek je pouziti funkci ktere ukladaji return taky na obycejny datovy zasobnik. Taky musi programator videt ze funkce nezmeni pozici datoveho zasobniku. U Forthu celkem snadne kdyz slovo ma v popisu ( a -- b ). Proste ze jen zmeni prvni hodnotu na zasobniku. Vtip je v tom ze ten zasobnik je implementovan tak ze HL je vrchol, DE je druha hodnota a (SP) az treti. A instrukce call to prirozene uklada na (SP), takze az za prvni 2 hodnoty! Takze mam pristup k prvnim dvou hodnotam(parametrum) funkce a nikde me nezavazi return na zasobniku! :beer: A instrukce ret zase vyzvedava pro me az treti polozku. A kdyz kouknu na kod tak vidim ze funkce pracuje jen s prvnimi dvema hodnotami, takze nic nemusim resit a misto CALL,COLON,SEMICOLON a EXIT volam jejich zasobnikove varianty s S na zacatku(SEXIT :lol: ).

Vysledek vypada podle me fakt dobre: https://github.com/DW0RKiN/M4_FORTH/blo ... /fib1x.asm
A je perfektne citelny clovekem.
Puvodni rekurzivni Fibonacci1 pomoci maker pasma trval 48minut a 55.91s.
Varianta s optimalizaci spojeni pouzitych slov, ale bez pouziti smycek a funkci na datovem zasobniku trva 32m 40.67s.
Tato varianta trva 18m 49.04s!

_________________
Z80 Forth compiler (ZX Spectrum 48kb): https://codeberg.org/DW0RKiN/M4_FORTH


Nahoru
 Profil  
 
 Předmět příspěvku: Re: Macro FORTH
PříspěvekNapsal: 22.05.2020, 14:16 
Offline
Óm Nejvyšší
Uživatelský avatar

Registrován: 28.01.2016, 23:57
Příspěvky: 3756
Has thanked: 213 times
Been thanked: 388 times
Mozna by sis mel precist "Moving FORTH" od Brada Rodrigueze, minimalne zacatek - dost se tam venuje jednak ruznym zpusobum implementace FORTHu, vcetne odkazu na dalsi zajimavou literaturu, a popisuje tam i ruzne optimalizace zasobniku: https://www.bradrodriguez.com/papers/moving1.htm
Registry pro prvni polozky na zasobniku se pouzivaji celkem casto, a jsou implementovane transparentne, neni zapotrebi nejakych specialnich slov.

_________________
Nikdy nediskutujte s blbcem. Stáhne vás na svoji úroveň a vyhraje zkušeností.


Nahoru
 Profil  
 
 Předmět příspěvku: Re: Macro FORTH
PříspěvekNapsal: 22.05.2020, 14:32 
Offline
Pan Štábní

Registrován: 23.06.2013, 23:49
Příspěvky: 1120
Has thanked: 100 times
Been thanked: 161 times
Dobre, podivam se na to zda to dokazi pochopit, kdyz neumim anglicky. Je mi jasne ze jsem objevil kolo. Ono to dokonce vypada, ze co vlastne resim. Vzdyt kdybych to psal v assembleru tak taky strcim parametry do registru a neresim return. Tohle je ale prece jenom jine. Protoze tady vim, ze to mohu volat rekurzivne. A vsechny casti maji pevne dane co kde lezi. Je to na zasobniku. To urcuje co je pevne a co lze menit. A muzu nejakou funkci nahradit jinou a bude to fungovat, protoze si to kazda nebude resit jinak. Rikas ze se tomu rika transparentne?

Ja taky nemam kvuli tomu specialni slova. Ty jsou jen proto, ze kdyz se na neco divas zpetne tak vidis, ze neco si nemusel delat, protoze ty slova jsou napsany obecne, aby platili pokazde. Neco by slo resit pres peephole optimalizace jako kdyz mam za sebou PUSH HL a POP HL. Nebo EXX a EXX kdyz jedno slovo tim konci a druhe zacina. Neco uz je slozitejsi jako to DUP_PUSH_LE_IF(). A spojeni slov mam kvuli lepsimu generovani assembleru. Tohle propojeni by dokazal napr. sed spusteny pred M4.

PS: Ten odkaz uz jsem zahledl kdyz jsem hledal informace o Forthu.

_________________
Z80 Forth compiler (ZX Spectrum 48kb): https://codeberg.org/DW0RKiN/M4_FORTH


Nahoru
 Profil  
 
 Předmět příspěvku: Re: Macro FORTH
PříspěvekNapsal: 22.05.2020, 14:59 
Offline
Pan Štábní

Registrován: 23.06.2013, 23:49
Příspěvky: 1120
Has thanked: 100 times
Been thanked: 161 times
Jeste jsem chtel rici jak jsem si navrhl ten zasobnik na zacatku na (SP),DE,HL protoze jsem videl slova jako swap a ex DE,HL na to sedi jako prdel na hrnec. Pak se mi libilo ze vlatne rovnou i scitani udelam pres add HL, DE atd.
Postupne jsem ale videl i negativa, nekdy kdyz prepinam na stinove registry tak by bylo lepsi mit vse v (SP). Dale jsem videl ze sice scitani pouziva add HL, DE ale pak stejne odstranim DE a musim nacist neco z (SP). Takze uz je jedno zda pisi
Kód:
add HL,DE
pop DE
nebo
Kód:
pop DE
add HL, DE
a zasobnik je jen (SP) a HL.
No ale ted kdyz zase vidim ze mam diky tomu volne 2 parametry ve funkcich a snadnou implementaci s jednim zasobnikem tak mi zase (SP),DE,HL dela radost. .)

I to mysleni jak je Forth neefektivni kdyz ma konstrukce typu "hodnota1 hodnota2 podminka if" kde podminka nacte 2 polozky ze zasobniku a vyplivne jednu typu TRUE/FALSE. if nacte polozku a vhodnoti ji. Takze vubec nevyuzijeme vsech vyhod Z80. carry atd. Je blbost. Protoze "podminka if" je idea. V implementaci to muze byt jedno slovo. Pouzijeme vsech priznaku co to jde. Zadne hrani z TRUE/FALSE. Programator napise neco a program vykona neco jine, ale rychleji se shodnym vysledkem. Takze nakonec Forth je genialni. Protoze to pujde napsat na procesoru co ma fakt jen flag zero, ale i na Z80 a efektivne. V tomhle pripade nejde myslet ze Forth nevyuzije plny potencial Z80 jak jsem si myslel nedavno. Je to o implementaci.

_________________
Z80 Forth compiler (ZX Spectrum 48kb): https://codeberg.org/DW0RKiN/M4_FORTH


Nahoru
 Profil  
 
 Předmět příspěvku: Re: Macro FORTH
PříspěvekNapsal: 27.05.2020, 18:32 
Offline
Pan Štábní

Registrován: 23.06.2013, 23:49
Příspěvky: 1120
Has thanked: 100 times
Been thanked: 161 times
Nevite nekdo proc intel ma instrukce pro nasobeni kde rozlisuje nasobeni se znamenkem a bez znamenka? I na netu jsou obcas algoritmy pro nasobeni na Z80 popsany napriklad unsigned. A vite co, je to jedno.

13*31 = 0x0D * 0x1F = 0x193 = 403
-13*31=0xFFF3 * 0x1F = 0x1EFE6D = 0xFE6D = -403
13*-31=0x0D * 0xFFE1 = 0xCFE69 = 0xFE6D = -403
-13*-31 = 0xFFF3 * 0xFFE1 = 0xFFD40193 = 0x193 = 403

Usetrilo me to praci s vymyslenim rutiny pro nasobeni 16bit * 16 bit a vysledkem 16 bit s korektnim pretecenim. :like:

_________________
Z80 Forth compiler (ZX Spectrum 48kb): https://codeberg.org/DW0RKiN/M4_FORTH


Nahoru
 Profil  
 
 Předmět příspěvku: Re: Macro FORTH
PříspěvekNapsal: 27.05.2020, 18:42 
Offline
Pan Štábní
Uživatelský avatar

Registrován: 24.05.2018, 22:32
Příspěvky: 1980
Bydliště: Most, Praha
Has thanked: 874 times
Been thanked: 699 times
Protože to funguje jen když má vstup a výstup stejný počet bitů. Instrukce násobení mají výstup 2x větší než vstup a tam to nesouhlasí.

_________________
i++ (INC) increment
i-- (DEC) decrement
i@@ (EXC) excrement


Nahoru
 Profil  
 
 Předmět příspěvku: Re: Macro FORTH
PříspěvekNapsal: 27.05.2020, 18:47 
Offline
Pan Štábní

Registrován: 23.06.2013, 23:49
Příspěvky: 1120
Has thanked: 100 times
Been thanked: 161 times
Pokud nekdo potrebujete vynasobit 16 bitovou hodnotu kladnou konstantou tak jsem pro to udelal v M4 makro ktere vygeneruje rovnou posloupnost instrukci. Neni uplne nejlepsi pro vsech 65536 variant, ale celkem slusny. M4 neni uplne idealni pro psani slozitych programu, takze jsem musel hledat nejsnazsi reseni. M4 nema zadny IF. Ma funkci pro porovnani shodnosti retezcu: ifelse(retezecA,retezecB,vypsani_retezce_kdyz_A_je shodny_s_B,vypsani_retezce_kdyz_neni)

popripadne ifelse(A,B,"A=B",C,D,"C=D",...) kde kdyz najde prvni rovnost tak to opusti makro. Takze to by jeste slo, ale v M4 nemuzete odsazovat protoze jakykoliv znaky se proste budou tisknout... :D To se mi podarilo trosku obejit, ale na vysvetleni proc nechcete psat neco komplikovaneho v M4 to postaci. M4 ale umi zase jine triky, kdyz mate promennou, ktera na konci se sama predefinuje.
Kód:
define("PLUS_DE","
   ld D, H
   ld E, L define("PLUS_DE", "
   ex DE, HL
   add HL, DE
   ex DE, HL")"

Takze kdyz poprve pouzijete PLUS_DE tak to jen nakopiruje HL a vsechny dalsi pouziti to pricte k DE obsah HL. S tim zanorovanim je to proste uplne jiny uvazovani.

Makro je tady:
https://github.com/DW0RKiN/M4_FORTH/blob/master/M4/arithmetic.m4
Potrebujete pred zavolanim udelat changequote(`{', `}')dnl

Kód:
    ld   HL, 0x0000     ; 3:10      0*


    add  HL, HL         ; 1:11      2* 2x  Variant: 2^a

    ld    B, H          ; 1:4       3* Variant: 2^a + 2^b
    ld    C, L          ; 1:4       3* save 1x
    add  HL, HL         ; 1:11      3* 2x
    add  HL, BC         ; 1:11      3* HL + save

    add  HL, HL         ; 1:11      4* 2x  Variant: 2^a
    add  HL, HL         ; 1:11      4* 4x

    ld    B, H          ; 1:4       5* Variant: 2^a + 2^b
    ld    C, L          ; 1:4       5* save 1x
    add  HL, HL         ; 1:11      5* 2x
    add  HL, HL         ; 1:11      5* 4x
    add  HL, BC         ; 1:11      5* HL + save

    add  HL, HL         ; 1:11      6* 2x
    ld    B, H          ; 1:4       6* Variant: 2^a + 2^b
    ld    C, L          ; 1:4       6* save 2x
    add  HL, HL         ; 1:11      6* 4x
    add  HL, BC         ; 1:11      6* HL + save

    ld    B, H          ; 1:4       7* Variant: 2^a - 2^b
    ld    C, L          ; 1:4       7* save 1x
    add  HL, HL         ; 1:11      7* 2x
    add  HL, HL         ; 1:11      7* 4x
    add  HL, HL         ; 1:11      7* 8x
    or    A             ; 1:4       7*
    sbc  HL, BC         ; 2:15      7* HL - save

    add  HL, HL         ; 1:11      8* 2x  Variant: 2^a
    add  HL, HL         ; 1:11      8* 4x
    add  HL, HL         ; 1:11      8* 8x

    ld    B, H          ; 1:4       9* Variant: 2^a + 2^b
    ld    C, L          ; 1:4       9* save 1x
    add  HL, HL         ; 1:11      9* 2x
    add  HL, HL         ; 1:11      9* 4x
    add  HL, HL         ; 1:11      9* 8x
    add  HL, BC         ; 1:11      9* HL + save

    add  HL, HL         ; 1:11      10* 2x
    ld    B, H          ; 1:4       10* Variant: 2^a + 2^b
    ld    C, L          ; 1:4       10* save 2x
    add  HL, HL         ; 1:11      10* 4x
    add  HL, HL         ; 1:11      10* 8x
    add  HL, BC         ; 1:11      10* HL + save

    ld    B, H          ; 1:4       11* Variant: 2^a + 2^b + 2^c
    ld    A, L          ; 1:4       11* save 1x
    add  HL, HL         ; 1:11      11* 2x
    add   A, L          ; 1:4       11* +
    ld    C, A          ; 1:4       11* +
    ld    A, B          ; 1:4       11* +
    adc   A, H          ; 1:4       11* +
    ld    B, A          ; 1:4       11* + save 2x
    add  HL, HL         ; 1:11      11* 4x
    add  HL, HL         ; 1:11      11* 8x
    add  HL, BC         ; 1:11      11* HL + save

    add  HL, HL         ; 1:11      12* 2x
    add  HL, HL         ; 1:11      12* 4x
    ld    B, H          ; 1:4       12* Variant: 2^a + 2^b
    ld    C, L          ; 1:4       12* save 4x
    add  HL, HL         ; 1:11      12* 8x
    add  HL, BC         ; 1:11      12* HL + save

    ld    B, H          ; 1:4       13* Variant: 2^a + 2^b + 2^c
    ld    A, L          ; 1:4       13* save 1x
    add  HL, HL         ; 1:11      13* 2x
    add  HL, HL         ; 1:11      13* 4x
    add   A, L          ; 1:4       13* +
    ld    C, A          ; 1:4       13* +
    ld    A, B          ; 1:4       13* +
    adc   A, H          ; 1:4       13* +
    ld    B, A          ; 1:4       13* + save 4x
    add  HL, HL         ; 1:11      13* 8x
    add  HL, BC         ; 1:11      13* HL + save

    add  HL, HL         ; 1:11      14* 2x
    ld    B, H          ; 1:4       14* Variant: 2^a - 2^b
    ld    C, L          ; 1:4       14* save 2x
    add  HL, HL         ; 1:11      14* 4x
    add  HL, HL         ; 1:11      14* 8x
    add  HL, HL         ; 1:11      14* 16x
    or    A             ; 1:4       14*
    sbc  HL, BC         ; 2:15      14* HL - save

    add  HL, HL         ; 1:11      2*27* 2x
    ld    B, H          ; 1:4       2*27* Variant: 2^a - 2^b - 2^c
    ld    A, L          ; 1:4       2*27* save 2x
    add  HL, HL         ; 1:11      2*27* 4x
    add  HL, HL         ; 1:11      2*27* 8x
    add   A, L          ; 1:4       2*27*
    ld    C, A          ; 1:4       2*27* +
    ld    A, B          ; 1:4       2*27* +
    adc   A, H          ; 1:4       2*27* +
    ld    B, A          ; 1:4       2*27* + save 8x
    add  HL, HL         ; 1:11      2*27* 16x
    add  HL, HL         ; 1:11      2*27* 32x
    add  HL, HL         ; 1:11      2*27* 64x
    or    A             ; 1:4       2*27*
    sbc  HL, BC         ; 2:15      2*27* HL - save

    add  HL, HL         ; 1:11      1012* 2x
    add  HL, HL         ; 1:11      1012* 4x
    ld    B, H          ; 1:4       1012* Variant: 2^a - 2^b - 2^c
    ld    A, L          ; 1:4       1012* save 4x
    add  HL, HL         ; 1:11      1012* 8x
    add   A, L          ; 1:4       1012*
    ld    C, A          ; 1:4       1012* +
    ld    A, B          ; 1:4       1012* +
    adc   A, H          ; 1:4       1012* +
    ld    B, A          ; 1:4       1012* + save 8x
    rr    H             ; 2:8       1012*
    rr    L             ; 2:8       1012*
    ld    H, L          ; 1:4       1012*
    ld    L, 0x00       ; 2:7       1012* 1024x
    or    A             ; 1:4       1012*
    sbc  HL, BC         ; 2:15      1012* HL - save

_________________
Z80 Forth compiler (ZX Spectrum 48kb): https://codeberg.org/DW0RKiN/M4_FORTH


Nahoru
 Profil  
 
 Předmět příspěvku: Re: Macro FORTH
PříspěvekNapsal: 27.05.2020, 18:49 
Offline
Pan Štábní

Registrován: 23.06.2013, 23:49
Příspěvky: 1120
Has thanked: 100 times
Been thanked: 161 times
Panda38 píše:
Protože to funguje jen když má vstup a výstup stejný počet bitů. Instrukce násobení mají výstup 2x větší než vstup a tam to nesouhlasí.


Jak proste! :D Diky.

A pri doplneni vstupu na velikost vystupu uz musime vedet zda nejvyssi bit je znamenko a doplnit to 0xffff pokud je jednickkovy a nebo stale 0x0000.

_________________
Z80 Forth compiler (ZX Spectrum 48kb): https://codeberg.org/DW0RKiN/M4_FORTH


Nahoru
 Profil  
 
 Předmět příspěvku: Re: Macro FORTH
PříspěvekNapsal: 27.05.2020, 19:04 
Offline
Pan Štábní

Registrován: 23.06.2013, 23:49
Příspěvky: 1120
Has thanked: 100 times
Been thanked: 161 times
Jinak co ta rutina neumi. Neumi vzdy spravne resit kdyz mame souvisly blok shodnych nulovych bitu, kdy by bylo efektivnejsi si nekam ulozit (treba do A) hodnotu low a pak misto opakovaneho "add HL, HL" udelat "ld H,A \ ld L,0". Protoze to uz chce cedet zda A nevyuzivame, zda nechceme ukladat hodnotu 0.25 treba atd. Neumi to poznat rozdil mezi:
Kód:
ld L, 0
or A
sbc HL, DE
a
Kód:
ld L, 0
or A
add HL, HL
sbc HL, DE
a tak nemuzeme prvni variantu zmenit na
Kód:
xor A
ld L, A
sbc HL, DE
.
Vsechno by v M4 slo. Ale fakt netusim jak to udelat citelne.

Ohledne teorie pro nasobeni konstantou. Asi nejlepsi reseni je umet prevest to cislo na format: number = 2^a + 2^b - 2^c + 2^d + ... - ... kde se budeme snazit mit co nejmene clenu. Jak to udelat matematicky fakt nevim.

Ja proste porovnavam pocet jednickovych bitu pro variantu: number = 2^a + 2^b + 2^c ...

s poctem nulovych bitu v (n-1) pro variantu: number = 2^(a+1) - ( 2^e + 2^f + ...)

Imho by to melo jit nejak tak, ze kdyz mame v cisle vetsi blok jednickovych bitu tak od nej odecteme nulovy bit co je pod nema a vznikne tak z "0 1 1 1 1 1 0 0 0" - "1 0 0" --> "1 0 0 0 0 0 0 0 0". Dokud nemame ty bity dost nahodne rozesety a to proste poscitame.
Takze nejlepsi je se podivat na binarni format a popremyslet a poscitat pocet bitu kdyz to udelam takhle a pocet bitu kdyz zkusim tohle...

PS: Ten skript umi preskocit 7 navazujicich nul pomoci ld H,L \ ld L,0 a 6 nul ze to prvne vydeli dvema, protoze si to neulozil... .) Pripadne blok jednicek pokud se jedna o odcitaci variantu.
PS: Nasobi se HL*konstanta s tim ze v DE mame data ktere musi byt zachovana. Proto taky se zacne DE pouzivat az od vypoctu s ctyrmi cleny.
Kód:
    ld    B, D          ; 1:4       12345* Variant: 2^a + 2^b + 2^c + ...
    ld    C, E          ; 1:4       12345*
    ld    D, H          ; 1:4       12345*
    ld    E, L          ; 1:4       12345* save 1x
    add  HL, HL         ; 1:11      12345* 2x
    add  HL, HL         ; 1:11      12345* 4x
    add  HL, HL         ; 1:11      12345* 8x
    ex   DE, HL         ; 1:4       12345* +
    add  HL, DE         ; 1:11      12345* + save 8x
    ex   DE, HL         ; 1:4       12345* +
    add  HL, HL         ; 1:11      12345* 16x
    ex   DE, HL         ; 1:4       12345* +
    add  HL, DE         ; 1:11      12345* + save 16x
    ex   DE, HL         ; 1:4       12345* +
    add  HL, HL         ; 1:11      12345* 32x
    ex   DE, HL         ; 1:4       12345* +
    add  HL, DE         ; 1:11      12345* + save 32x
    ex   DE, HL         ; 1:4       12345* +
    rr    H             ; 2:8       12345*
    rr    L             ; 2:8       12345*
    ld    H, L          ; 1:4       12345*
    ld    L, 0x00       ; 2:7       12345* 4096x
    ex   DE, HL         ; 1:4       12345* +
    add  HL, DE         ; 1:11      12345* + save 4096x
    ex   DE, HL         ; 1:4       12345* +
    add  HL, HL         ; 1:11      12345* 8192x
    add  HL, DE         ; 1:11      12345* HL + save
    ld    D, B          ; 1:4       12345*
    ld    E, C          ; 1:4       12345*

_________________
Z80 Forth compiler (ZX Spectrum 48kb): https://codeberg.org/DW0RKiN/M4_FORTH


Nahoru
 Profil  
 
Zobrazit příspěvky za předchozí:  Seřadit podle  
Odeslat nové téma Odpovědět na téma  [ Příspěvků: 598 ]  Přejít na stránku Předchozí  1, 2, 3, 4, 5 ... 40  Další

Všechny časy jsou v UTC + 1 hodina [ Letní čas ]


Kdo je online

Uživatelé procházející toto fórum: Žádní registrovaní uživatelé a 29 návštevníků


Nemůžete zakládat nová témata v tomto fóru
Nemůžete odpovídat v tomto fóru
Nemůžete upravovat své příspěvky v tomto fóru
Nemůžete mazat své příspěvky v tomto fóru
Nemůžete přikládat soubory v tomto fóru

Hledat:
Přejít na:  
Založeno na phpBB® Forum Software © phpBB Group
Český překlad – phpBB.cz