OldComp.cz https://www.oldcomp.cz/ |
|
Macro FORTH https://www.oldcomp.cz/viewtopic.php?f=124&t=8564 |
Stránka 1 z 40 |
Autor: | _dworkin [ 11.05.2020, 17:16 ] |
Předmět příspěvku: | Macro FORTH |
Mirnou odbockou zkoumanim jak funguje C na Z80. Kde jsem porad narazel na problemy, u kterych jsem jen ztracel hromadu casu a stejne jsem nebyl schopen je vyresit, protoze na to asi fakt nemam... Mel jsem problem spustit i "jednoduche" compilery a porad videl chybove vystupy z flex nebo bison. A nedokazal jsem napsat lepsi chybovou funkci, ktera by pekne vypsala cislo radky a sloupce kde chyba nastala (dospel jsem jen k tomu ze jsem umel vypsat token kdery mu vadi). Zadne hotove reseni jsem proste neskompiloval ...jsem se dostal k programovacimu jazyku FORTH. A zjistil jsem, ze to neni az tak slozite a ze dokazi napsat "prekladac" jen pomoci maker v pasmu. Ze stacilo sesmolit v asembleru funkci na vypsani cisla, funkci na vypsani retezce a funkci na zalomeni radku, funkci na 16 bitove nasobeni (na deleni jsem se vybodl). Na zacatku pridat ulozeni stinovych registru a za to uz jen napraskat makra. Ulozit to jako soubor ktery prilinkuji ke svemu programu a ono to fakt funguje! Ok, ma to nejake omezeni... Nevypada to uplne jako FORTH protoze proste nemuzu makrem predefinovat > na seznam instrukci. Musim to prejmenovat na "greater". Tecku pro vypsani cisla na zasobniku predelat na "DOT". Dalsi vec je ze prikazy nemuzou byt na stejnem radku jako ve FORTHu ale pod sebou. Protoze kazdy dalsi prikaz je chapan jako parametr prvniho makra na radku. Trosku se to hodi protoze FORTH pracuje tak ze data ma na zasobniku a v polske notaci. Takze kdyz je neco podivne napravo je to proste pomocny parametr. Napr. "NEW 5" by ve FORTHu bylo zapsano jen "5". Dale nedokazi napsat: IF ... ELSE ... THEN Protoze IF a ELSE je uz zabrany a vnitrne ten if skoci na ELSE pokud nesplni podminku a ELSE vnitrne pred svym zacatkem skace na THEN a pak definuje label pro skok z IF. Takze po trosku marnem googleni a nahodnem zkoumani co pasmo umi jsem se dostal k zapisu: _IF jednoznacnejmeno ... _ELSE jednoznacnejmeno ... _THEN jednoznacnejmeno Kde makra _IF, _ELSE, _THEN vypadaji: Kód: ; ## Vetveni _IF MACRO name name: ; jen pro kontrolu shodnych jmen LD A, H OR L EX DE, HL POP DE jp z, name##_else ENDM IFZ MACRO name name: ; jen pro kontrolu shodnych jmen jp nz, name##_else ENDM _ELSE MACRO name if not defined name .warning Parametr macra _ELSE neni definovan! Preklep? endif jp name##_then name##_else: ENDM _THEN MACRO name if not defined name .warning Parametr macra _THEN neni definovan! Preklep? Musi byt shodny si _IF endif if not defined name##_else name##_else: endif name##_then: ENDM Dalse jsem resil smycku "stop index DO ... LOOP". Vnitrne nacte v DO do zasobniku navratovych adres stop a index a za tim vytvori label pro navrat na zacatek. LOOP zase nacte ze zasobniku stop a index, zvedne index, porovna ho se stop a zjisti zda ma skoncit nebo to zase ulozit na zasobnik navratovych adres a skocit na zacatek. Tzn. potrebuji zase jmeno pro novy label smycky. Takze macro zapis je: Kód: NEW stop Ten jednoznacny nazev by tam byt nemusel protoze smycky se nemohou krizit a byt jen vnorene. Takze by sla ta adresa ukladat na zasobnik, ale bylo by to pomalejsi... Ale pokud je stop konstanta tak by stacilo kdyby ho znal jen LOOP. Tak jsem napsal alternativni smycku:NEW index DO smycka_1 ... LOOP smycka_1 Kód: XDO smycka_2, index Ma zase nevyhodu, ze tahle bezi jen na konstantach a nemuze ji program pres zasobnik menit.... XLOOP smycka_2, stop Vypis retezcu se misto ."Hello Word!\n" resi jako XP_STRING "Hello Word!\r", 12. Dvanact je pocet pismen retezce. Neumim to spocitat sam a je dulezite ho napsat spravne. Jinak bude pokracovat program v retezci. Kdyz se zada vetsi cislo tak to zase bude snazit tisknout znaky s kodem nuly. "\r" je pro zalomeni radku. Basic proste zalomi kdyz mu predhodite 0x0D, nebo 13 dekadicky. Ne kdyz mu predhodite 0xA po "\n". Jinak se zalamuje radek stejne jako ve FORTHu pres CR. Posledni vetsi zmena je u definice slov. FORTH napise neco jako ": deset 10 0 DO I . LOOP ;" a po zadani deset to napise "0 1 2 3 4 5 6 7 8 9". Pres macra to jde takto: Kód: _BEGIN deset
XDO smycka, 0 XI DOT XLOOP smycka, 10 _END deset |
Autor: | _dworkin [ 11.05.2020, 17:27 ] | ||
Předmět příspěvku: | Re: Macro FORTH | ||
Prikladam aktualni verzi (takze uz asi starou kdyz to ctete ) definic maker. Vzorovy program vypada nejak takto Kód: SP_fce EQU 45000 ; Povina promnena ktera nastavuje pozici zasobniku navratovych adres. Leze k nizsim adresam jako datovy. Ale slo by to predelat aby sly s datovym proti sobe. START EQU 32768 RUNTIME EQU 143 textsize equ textend-text ORG START include Forth_mini.asm MAIN: ; na tuhle adresu skace basic je rovna START + RUNTIME, pred ni je funkce na vypsani cisel, nasobeni atd. NEW text NEW textend-text P_STRING XP_STRING "Ahoj svete!\r", 12 STOP ; povinne makro ktere zase nacte stinove registry pred navratem do basicu text defb 'Hello, World!', 13 textend Hrozne se me na tom libi ze je to vlastne cely asembler, ale vypada to jako FORTH.
|
Autor: | _dworkin [ 11.05.2020, 17:30 ] |
Předmět příspěvku: | Re: Macro FORTH |
Na tehle adrese https://theultimatebenchmark.org/ jsou definovany nejake programky ve FORTHu a jsou k tomu i casy. V podstate jsem postupoval tak ze jsem si nasel ten nejednodussi a zkousel ho napsat, koukal co me chybi a pridaval a pridaval. Takze jsem implementoval GCD1, GCD2, Fib1, Fib2. |
Autor: | _dworkin [ 11.05.2020, 17:49 ] |
Předmět příspěvku: | Re: Macro FORTH |
GCD1 Kód: SP_fce EQU 45000 ZX ho zvladne za 10.27s.START EQU 32768 debug EQU 0 ORG START include Forth_mini.asm RUN gcd1_bench STOP ; : gcd ( a b -- gcd ) ; OVER IF ; BEGIN ; DUP WHILE ; 2DUP U> IF SWAP THEN OVER - ; REPEAT DROP ELSE ; DUP IF NIP ELSE 2DROP 1 THEN ; THEN ; ; : gcd1-bench 100 0 DO ; 100 0 DO j i gcd drop loop ; loop ; ; ( a b -- gcd ) _BEGIN gcd OVER ; x1 x2 -- x1 x2 x1 _IF velka BEGIN smycka DUP WHILE smycka DUP2 greater ;U> _IF mala SWAP ; x1 x2 -- x2 x1 _THEN mala OVER ; x1 x2 -- x1 x2 x1 minus ; - REPEAT smycka DROP _ELSE velka DUP _IF dalsi NIP _ELSE dalsi if 1 DROP2 NEW 1 else CHANGE_TOP 1 NIP endif _THEN dalsi _THEN velka _END gcd _BEGIN gcd1_bench XDO vnejsi, 0 XDO vnitrni, 0 if debug XJ SDOT XI SDOT RUN gcd XP_STRING "res: ", 5 DOT CR XLOOP vnitrni, 4 XLOOP vnejsi, 5 else XJ XI RUN gcd DROP XLOOP vnitrni, 100 XLOOP vnejsi, 100 endif _END gcd1_bench Kód: System Forth Benchmark Time (sec/round) IBM PS/2 L40SX DX-Forth GCD1 0m29s Amstrad PPC 512 DX-Forth GCD1 0m48s IBM PS/2 L40SX DX-Forth gcd1 0m15s Raspberry Pi ARM 700Mhz Gforth 0.7.0 gcd1 0m04s " " GCD1 2m14s SUN SparcStation 10 TI TMS390255 OpenFirmware GCD1 0,51s SUN Ultra 1 200 Mhz UltraSprac OpenBoot 3.25 GCD1 0,08s Atari Falcon 68060 f68kans GCD1 0,063s Compaq Deskpro P166 pForth V27 GCD1 0,002s Apple iMac G3 400Mhz pForth V27 GCD1 0,063s DEC 3000 400s pForth V27 GCD1 0,483 SUN Ultra 1 Creator 3D pForth V27 GCD1 0,022s C64 DurexForth 1.6.1 (STC) GCD 1 60s Amiga 500 mit ACA1233n-Turbokarte (68030 @ 40 MHz) JForth 3.1 Delta Research (Phil Burk) GCD 1 0.4s Enterprise 128 IS-Forth von B. Tanner GCD 1 78s Sinclair QL M68008 7,5 Mhz Forth79 (G.W.Jackson) GCD 1 21 Nixdorf 8810 M15 (8Mhz i286) L.O.V.E. Forth GCD 1 6 Robotron A 7150 i8086/8087 Multibus ~5Mhz VolksForth MS-DOS (ITC) GCD 1 25 Yodabashi Formula 1 Z80 4Mhz VolksForth CP/M (ITC) GCD 1 42 Scheider Tower AT 220 i286 10Mhz VolksForth MS-DOS (ITC) GCD 1 5 Amstrad NC100 Z80 4.606Mhz VolksForth CP/M (ITC) GCD 1 38.1 Commodore C64 6510 Audiogenic Forth-64 GCD 1 215.52 Amiga 3000 68030 25Mhz jforth GCD 1 0.64 iBook PPC 750lx (G3) 600Mhz OpenFirmware GCD 1 0.024 Atmega16 8MHz amForth 4.4 GCD 1 7.12 Mupid II (BTX Decoder) FIG-Forth 1.1 GCD 1 205s Mupid II (BTX Decoder) Camel Forth 1.01 GCD 1 116s Uznavam ze to neni fer, protoze porovnavam interpret s kompilovanym FORTHem. Takze je rychlejsi a nechutne delsi. Protoze neni tokenizovany. A pro kazdy token nevola fci, ale rovnou tam vklada opakovane instrukce. ...Ale co si budeme povidat 80386SX @20 MHz to dava za 15 sekund... |
Autor: | _dworkin [ 11.05.2020, 18:00 ] |
Předmět příspěvku: | Re: Macro FORTH |
Dale jsem pokracoval s hledanim nejvyssiho spolecneho delitele pomoci benchmarku GCD2. Kód: SP_fce EQU 45000 Ktery Z80 zvlada za 11.5 vteriny a je stejne rychly jako Atmega16 8MHzSTART EQU 32768 debug EQU 0 ORG START include Forth_mini.asm RUN gcd2_bench STOP ; : gcd2 ( a b -- gcd ) ; 2DUP D0= IF 2DROP 1 EXIT THEN ; DUP 0= IF DROP EXIT THEN ; SWAP DUP 0= IF DROP EXIT THEN ; BEGIN 2DUP - ; WHILE 2DUP < IF OVER - ; ELSE SWAP OVER - SWAP ; THEN ; REPEAT NIP ; ; : gcd2-bench 100 0 DO ; 100 0 DO j i gcd2 drop loop ; loop ; _BEGIN gcd2 ; ( a b -- gcd ) test0double IFZ prvni DROP2 NEW 1 _EXIT gcd2 _THEN prvni test0 IFZ druhy DROP _EXIT gcd2 _THEN druhy SWAP test0 IFZ treti DROP _EXIT gcd2 _THEN treti BEGIN smycka DUP2 minus WHILE smycka DUP2 less _IF ctvrta OVER minus _ELSE ctvrta SWAP OVER minus SWAP _THEN ctvrta REPEAT smycka NIP _END gcd2 _BEGIN gcd2_bench XDO vnejsi, 0 XDO vnitrni, 0 if debug XJ SDOT XI SDOT RUN gcd2 XP_STRING "res: ", 5 DOT CR XLOOP vnitrni, 4 XLOOP vnejsi, 5 else XJ XI RUN gcd2 DROP XLOOP vnitrni, 100 XLOOP vnejsi, 100 endif _END gcd2_bench Kód: System Forth Benchmark Time (sec/round)
IBM PS/2 L40SX DX-Forth GCD2 0m42s SUN SparcStation 10 TI TMS390255 OpenFirmware GCD2 0,65s SUN Ultra 1 200 Mhz UltraSprac OpenBoot 3.25 GCD2 0,11s Atari Falcon 68060 f68kans GCD2 0,067s Asus EeePC 1000h (Atom N270 1.6Ghz) FreeBSD 9 FICL Bootloader GCD2 0.57s C64 DurexForth 1.6.1 (STC) GCD 2 70s A-ONE (Apple 1 Clone) mit 65C02 TaliForth 2 (STC) GCD 2 1m25s Steckschwein 8MHz 65c02 TaliForth 2 (STC) GCD 2 11.75s Robotron A 7150 i8086/8087 Multibus ~5Mhz VolksForth MS-DOS (ITC) GCD 2 30 Commodore C64 6510 Audiogenic Forth-64 GCD 2 84.84 Atmega16 8MHz amForth 4.4 GCD 2 10.5 Mupid II (BTX Decoder) FIG-Forth 1.1 GCD 2 188s Mupid II (BTX Decoder) Camel Forth 1.01 GCD 2 135s |
Autor: | _dworkin [ 11.05.2020, 18:14 ] |
Předmět příspěvku: | Re: Macro FORTH |
Rekurzivni Fibonacci1 byl trosku orisek. Vypadalo to ze je neco spatne. Neni, jen je to strasne pomale: Kód: SP_fce EQU 45000 Ale ZX nakonec dopocita za 48minut a 55.91 vterin. Zda se ze ta moje emulace druheho zasobniku neni uplne nejlepsi.START EQU 32768 debug EQU 0 ORG START include Forth_mini.asm RUN fib1_bench STOP ; : 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 ; _BEGIN fib1 DUP NEW 2 less _IF pod2 DROP NEW 1 _EXIT fib1 _THEN pod2 DUP decrement RUN fib1 SWAP decrement2 RUN fib1 plus _END fib1 _BEGIN fib1_bench if debug XDO vnitrni, 0 XI SDOT RUN fib1 DOT CR XLOOP vnitrni, 20 else XDO vnejsi, 0 XDO vnitrni, 0 XI RUN fib1 DROP XLOOP vnitrni, 20 XLOOP vnejsi, 1000 endif _END fib1_bench Kód: System Forth Benchmark Time (sec/round) Jedine co na to muzu rici je, ze to nikdo na osmibitech nezkousel a nebo se mu to nepodarilo. Nebo se nedockal...
DEC 3000-600 Alpha 21064 175Mhz pForth Fibonacci 1 0.0038 iBook PPC 750lx (G3) 600Mhz OpenFirmware Fibonacci 1 0.0026 Rockwell R1200-14, 2Mhz 65F12 RSC-Forth Fibonacci 1 16.09 Atmega16 8MHz amForth 4.4 Fibonacci 1 1.46 IBM L40X (386SX) VolksForth MS-DOS Fibonacci 1 0.36s SUN SparcStation 10 TI TMS390255 OpenFirmware Fib1 0,005s SUN Ultra 1 200 Mhz UltraSprac OpenBoot 3.25 Fib1 0,014s Compaq Deskpro P166 pForth V27 Fib1 0,061s Apple iMac G3 400Mhz pForth V27 Fib1 0,015s DEC 3000 400s pForth V27 Fib1 0,098s SUN Ultra 1 Creator 3D pForth V27 Fib1 0,052s NCR 3150 486SX/25Mhz+FPU=Linux 2.0.0 gforth 0.3.0 Fib1 1m79s MSP430FR5739, 8Mhz DCO intern MSP-EXP430FR5739 Experimenter Board CamelForth FIB1 100x 00'46':39 00'46':39 |
Autor: | _dworkin [ 11.05.2020, 18:31 ] |
Předmět příspěvku: | Re: Macro FORTH |
Posledni pan na holeni byl Fibonacci 2. Kód: SP_fce EQU 45000 Kterou Z80 zvladne za 12.1 vteriny. Coz je o trosku pomaleji nez 486.START EQU 32768 debug EQU 1 ORG START include Forth_mini.asm RUN fib2_bench STOP ; : fib2 ( n1 -- n2 ) ; 0 1 rot 0 do ; over + swap loop ; drop ; ; : fib2-bench 1000 0 do ; 20 0 do i fib2 drop loop ; loop ; _BEGIN fib2 if debug XP_STRING "input: ", 7 SDOT CR endif NEW 0 ; ( a 0 -- ) NEW 1 ; ( a 0 1 -- ) ROT ; ( 0 1 a -- ) NEW 0 ; ( 0 1 a 0 -- ) DO smycka ; stop index DO if debug PRINTSTACK CR endif OVER ; kopie druhe polozky na zasobniku plus SWAP LOOP smycka DROP _END fib2 _BEGIN fib2_bench if debug XDO bench_smycka, 0 XI RUN fib2 XP_STRING "res: ", 5 DOT CR XLOOP bench_smycka, 10 else XDO vnejsi, 0 XDO vnitrni, 0 XI RUN fib2 DROP XLOOP vnitrni, 20 XLOOP vnejsi, 1000 endif _END fib2_bench Kód: System Forth Benchmark Time (sec/round) Scheider Tower AT 220 i286 10Mhz VolksForth MS-DOS (ITC) Fibonacci2 8 C64 DurexForth 1.6.1 (STC) Fibonacci 2 1m57s Amiga 500 mit ACA1233n-Turbokarte (68030 @ 40 MHz) JForth 3.1 Delta Research (Phil Burk) Fibonacci 2 0.35s Enterprise 128 IS-Forth von B. Tanner Fibonacci 2 118.4s A-ONE (Apple 1 Clone) mit 65C02 TaliForth 2 (STC) Fibonacci 2 1m50s Steckschwein 8MHz 65c02 TaliForth 2 (STC) Fibonacci 2 15.23s Sinclair QL M68008 7,5 Mhz Forth79 (G.W.Jackson) Fibonacci 2 35 Robotron A 7150 i8086/8087 Multibus ~5Mhz VolksForth MS-DOS (ITC) Fibonacci 2 46 DEC 3000-600 Alpha 21064 175Mhz pForth Fibonacci 2 0.00001425 Amstrad 6128+ Z80A 4Mhz Uniforth Fibonacci 2 0.23 iBook PPC 750lx (G3) 600Mhz OpenFirmware Fibonacci 2 0.0027 Rockwell R1200-14, 2Mhz 65F12 RSC-Forth Fibonacci 2 0.05 Atmega16 8MHz amForth 4.4 Fibonacci 2 0.0047 Nixdorf 8810 M15 (8Mhz i286) L.O.V.E. Forth Fibonicci 2 8 IBM PS/2 L40SX DX-Forth Fib2 1m03s Amstrad PPC 512 DX-Forth Fib2 1m45s IBM PS/2 L40SX DX-Forth fib2 1m03s Apple II UltraWarp 13Mhz Apple II v. 3.2 Fib2 0m21s Apple II UltraWarp 13Mhz Apple GraForth Fib2 0m11s Apple II 1Mhz Apple II v. 3.2 Fib2 3m56s Apple II 1Mhz Apple GraForth Fib2 2m19s SUN SparcStation 10 TI TMS390255 OpenFirmware Fib2 0,2s SUN Ultra 1 200 Mhz UltraSprac OpenBoot 3.25 Fib2 0,06s Atari Falcon 68060 100mhz f68kans Fib2 0,0012s Asus EeePC 1000h (Atom N270 1.6Ghz) FreeBSD 9 FICL Bootloader Fib2 66s Atari Portfolio VolksForth 3.81 Fib2 35s Compaq Deskpro P166 pForth V27 Fib2 0,001s Apple iMac G3 400Mhz pForth V27 Fib2 0,001s SUN Ultra 1 Creator 3D pForth V27 Fib2 0,001s mc-CP/M Z80 4Mhz FIG-Forth 1.1 Fib2 1m19s Prof80 CP/M Z80 6Mhz FIG-Forth 1.1 Fib2 53s robotron K 1510, U 808 D (i8008), 480 kHz (auf FOSY Emulator) FOSY V1.2P 1988 (FIG) FIB2-BENCH 01:51:58 1h 51min 58s DEC 3000 400s pForth V27 Fib21 0,001s IBM L40S (386SX) mina (Fig-Forth) Fib2 (1000) 8s IBM L40X (386SX) F83 (Laxen & Perry) Fib2 (1000) 8s IBM L40X (386SX) GNU Forth 0.5.0 ec8086 Fib2 (1000) 24s " " Fib2 (1000) 1m46s HX-20 Epson Forth E1.0 Fib2 (1000) 3m16s Fignition (ATMEL) Fignition Forth fib2 (1000) 13s C64 (normal) Forth64 Fib2 (1000) 3m50s C64 (Turbo FPGA 6502) Forth64 Fib2 (1000) 16s Zilog Super-8 20Mhz Super8 Forth Fib2 (1000) 31s Samsung Galaxy Note 2 (Exynos 4core) Gforth Fib2 (1000) 0.01s PDP11 FIG-Forth 1.3 Fib2 (1000) 37s Mupid II (BTX Decoder) FIG-Forth 1.1 Fib2 (1000) 210s Mupid II (BTX Decoder) Camel Forth 1.01 Fib 2 (1000) 150s NCR 3150 486SX/25Mhz+FPU=Linux 2.0.0 gforth 0.3.0 Fib2 (2500) 9.2s PS: " " je asi vzdy "Sinclair Spectrum+ Aber Forth (FIG-Forth)". |
Autor: | _dworkin [ 11.05.2020, 18:33 ] |
Předmět příspěvku: | Re: Macro FORTH |
Tak to by mel byt konec spamovani. Rekl bych ze vzorovych ukazek je dost a prijde mi to tak snadne, ze kdo se tomu chce venovat tak to uz zvladne sam. .) Jen jsem chtel ukazat, ze tady jsou otevrene dvere a za nima spousta hracek. Hmm.. mozna jsem jeste zapomnel ze I J K u smycek ulozi na zasobnik aktualni hodnotu indexu. A kdyz smycky DO..LOOP a XDO..XLOOP uklada jiny pocet hodnot na zasobnik navratovych hodnot. Presne druha vzdy polovinu. Tak se musi volat II, JI = XK a nebo XI, XJ, XK. Ostatni se musi dodelat. Melo by to byt snadne protoze od XK se tam vklada konstanta tak ji staci zmeni. Slo by to i jako parametr makra. Jo a jeste slova co pracuji s dvojici hodnot. A to tak ze se k nem chovaji jako by to byla jedna 64 bitova hodnota. Maji dvojku na konci nazvu a ne na zacatku. : 2DUP ( a b -- a b a b ) OVER OVER ; 2DUP => DUP2 kde OVER dela kopii druhe hodnoty na vrchol a ne : 2DUP ( a b -- a b b b ) DUP DUP ; http://wiki.laptop.org/go/Forth_Lessons |
Autor: | Busy [ 11.05.2020, 21:58 ] |
Předmět příspěvku: | Re: Macro FORTH |
_dworkin píše: A zjistil jsem, ze to neni az tak slozite a ze dokazi napsat "prekladac" jen pomoci maker v pasmu. No ty brdo, tak to klobuk dolu ! Ja som sice s FORTH-om nikdy nic nemal (nestudoval, nepouzival), ale i tak musim uznat ze to mas riadne prespekulovane. |
Autor: | _dworkin [ 12.05.2020, 12:18 ] | |||
Předmět příspěvku: | Re: Macro FORTH | |||
Par uprav v zdrojovem souboru. Nejake optimalizace a pridani dalsich dvou typu smycek. Prvni (STACKDO x, STACKLOOP x, STACKI) kdy vime ze na zacatku i na konci smycky bude zasobnik na stejne adrese. Tzn. pokud ulozime nejake data tak se zase odeberou. Takze se da ulozit STOP a INDEX na zasobnik. Druha (FASTDO x, FASTLOOP x,FASTI x) je kdy vime ze se nepouzije rekurze. Ta smycka nebude bezet najednou vickrat. Takze STOP a INDEX jsou ulozeny primo v kodu. Moje motivace byla, ze jsem si zase nasel na netu nejake udaje ( sice pro jiny procesor, pro Z8 ale to neva ) a videl svoje nedostatky. Takze testy jsou aby smycka probehla presne milionkrat. Popripade, aby milionkrat ulozila 16 bitovou hodnotu. Dosazene casy jsou ulozeny primo v kodu. Kód: SP_fce EQU 39000 START EQU 32768 ORG START include Forth_mini.asm ; 1 000 000 x ( 32.8 s ) XDO smycka0, 0 NEW 60000 ; stop NEW 40000 ; index RUN test XLOOP smycka0, 50 STOP _BEGIN test DO smycka LOOP smycka _END test Kód: SP_fce EQU 39000 START EQU 32768 ORG START include Forth_mini.asm ; 1 000 000 x ( 19.76 s ) XDO smycka0, 0 NEW 60000 ; stop NEW 40000 ; index RUN test XLOOP smycka0, 50 STOP _BEGIN test FASTDO smycka FASTLOOP smycka _END test Kód: SP_fce EQU 39000 Ukladani:START EQU 32768 ORG START include Forth_mini.asm ; 1 000 000 x ( 9.32 s ) NEW 50 NEW 0 STACKDO smycka0 NEW 60000 ; stop $EA60 NEW 40000 ; index $9C40 RUN test STACKLOOP smycka0 STOP _BEGIN test STACKDO smycka STACKLOOP smycka _END test Kód: SP_fce EQU 39000 START EQU 32768 ORG START include Forth_mini.asm ; 1 000 000 x ( 47.58 s ) XDO smycka0, 0 NEW 60000 ; stop $EA60 NEW 40000 ; index $9C40 RUN test XLOOP smycka0, 50 STOP _BEGIN test FASTDO smycka NEW 20 FASTI smycka STORE ; vzhledem k tomu ze uklada 16 bitovou hodnotu a posunuje se po bajtech nahoru tak oblast zaplni nulama (hi($0014)) a na konci ulozi jednu 20. FASTLOOP smycka _END test Kód: SP_fce EQU 39000 START EQU 32768 ORG START include Forth_mini.asm ; 1 000 000 x ( 30.18 s ) NEW 50 NEW 0 STACKDO smycka0 NEW 60000 ; stop $EA60 NEW 40000 ; index $9C40 RUN test STACKLOOP smycka0 STOP _BEGIN test STACKDO smycka ; 20 I PUSH DE PUSH HL LD DE, 20 STORE ; vzhledem k tomu ze uklada 16 bitovou hodnotu a posunuje se po bajtech nahoru tak oblast zaplni nulama (hi($0014)) a na konci ulozi jednu 20. STACKLOOP smycka _END test A pro ukazku jeste jak ta STACK smycka skoro nic nedela: Kód: ; Smycka musi mit na konci stejny datovy zasobnik jako na zacatku
; pokud nema musi byt prvni a druha polozka na zasobniku nezmenena ( fyzicky HL a DE ) ; ( stop index -- stop index ) STACKDO MACRO name ; nemusime nic delat name: ENDM ; Discard the loop-control parameters for the current nesting level. STACKUNLOOP MACRO POP HL ; 1:10 index out POP DE ; 1:10 stop out ENDM ; To same co DUP ; ( a -- a a ) ; dalsi indexy nejsou definovany, protoze neni jiste jak to na zasobniku vypada. Pokud je tam hned dalsi smycka tak J lezi na (SP), K lezi na (SP+4) STACKI MACRO DUP ENDM ; ( stop index -- stop index++ ) STACKLOOP MACRO name if not defined name .warning Parametr macra FASTLOOP neni definovan! Preklep? Musi byt shodny s FASTDO endif INC HL ; 1:6 index++ LD A, L ; 1:4 SUB E ; 1:4 lo stop LD A, H ; 1:4 SBC A, D ; 2:7 hi stop JP c, name ; 3:10 ; 9:35 STACKUNLOOP ; 2:20 ENDM
|
Autor: | _dworkin [ 14.05.2020, 09:19 ] | ||
Předmět příspěvku: | Re: Macro FORTH | ||
z80asm nezvlada makra. Presneji vubec je jeste neumi. Odkazuje se ze pokud je potrebujete mate pouzit M4. Hrozny nazev. Pro google je M4 americka karabina a vsechno mozne, jen ne znackovaci jazyk. Mam pocit, ze nedavno o tom vysla serie na rootu. https://www.gnu.org/software/m4/manual/m4-1.4.17/html_node/Macro-index.html Chtel jsem to vyzkouset, protoze by to mel byt mocny nastroj a ne pouze to co umi pasmo. Kde nevim jak udelat nejakou promenou. Protoze pokud vim tak tam nejde udelat undefine, nebo redefine nebo tak. Takze kdyz se pise IF tak se tam musi rucne vymyslet a zadavat jednoznacny identifikator (jak se to rekne cesky? Nazev? Jmeno? ). Neumim anglicky a ... ok vlastne na tom nezalezi, kdyz to zkratim tak ukazi jeden trik co vznikl metodou pokus omyl. Kód: // ------ IF IF ELSE THEN THEN Kód: // ------ Mam radost. Protoze vstup je na jednom radku, bez pomocnych parametru a vypada presne jako vstup pro FORTH a vystup je citelny assembler. Jeste je tam potreba, aby umel kompiler "if", "not defined","endif", ale to uz me tak neboli. Mozna.. by M4 slo pouzit i na nejake optimalizace. Kdy sekvence "LOOP LOOP" vzdy zacina "EXX" a konci "EXX", protoze si jen hraje v zasobniku navratovych adres s pomoci HL', takze ta dvojice vytvori kod kde za sebou nasleduji "EXX EXX" bez toho, ze by tam byl nejaky skok. Takze kdyz se do zdrojaku kouka clovek tak se chyta za hlavu... On je vlastne cely kod FORTHu divny. Same hrani se zasobniky a prohazovani 16 bitovych hodnot. "PUSH xx POP xx" a "EX DE, HL" nebo "EX (SP), HL" a vypada to ze to nic nedela a je tam jen vata. Proste neco co mate potrebu odstranit kdyz pisete v assembleru a nahradit to za prohazovani hodnot mezi registry. LD A, H OR L EX DE, HL POP DE JP z, else101 LD A, H OR L EX DE, HL POP DE JP z, else102 JP endif102 else102: if not defined else102 else102: endif endif102: if not defined else101 else101: endif endif101: Vypada to ze pomoci M4 pujde vytvorit fakt "kompiler" FORTHu. Bez obezlicek v uprave zdrojaku. Nepocitam teda ze 100%. Kdy budete menit nejake slovo v prubehu programu, ale nejaky jednoduchy programy by to zvladnout melo.
|
Autor: | Busy [ 14.05.2020, 09:28 ] |
Předmět příspěvku: | Re: Macro FORTH |
_dworkin píše: z80asm nezvlada makra. Presneji vubec je jeste neumi. Skus aj nas oblubeny SjASMPlus. Ten ma nielen makra, ale ma v sebe plnohodnotny skriptovaci jazyk Lua, takze co by nahodou neslo makrami, tak sa da naskriptovat "rucne"._dworkin píše: Chtel jsem to vyzkouset, protoze by to mel byt mocny nastroj a ne pouze to co umi pasmo. Kde nevim jak udelat nejakou promenou. V sjasmplus si premennu urobis lahko, pomocou znaku =Kód: konstanta equ hodnota ; nesmie sa menit
premenna equ hodnota ; moze sa predefinovat na inu hodnotu |
Autor: | _dworkin [ 14.05.2020, 09:29 ] |
Předmět příspěvku: | Re: Macro FORTH |
Predpokladam ze si myslel asi Kód: konstanta equ hodnota ; nesmie sa menit ?
premenna = hodnota ; moze sa predefinovat na inu hodnotu |
Autor: | _dworkin [ 14.05.2020, 11:32 ] |
Předmět příspěvku: | Re: Macro FORTH |
Hmm.. nakonec to nebude tak snadne. Zacal jsem prepisovat DO LOOP do M4 a doslo me, ze pouzit jedinou promenou na propojeni souvisejicich DO a LOOP mezi sebou nebude stacit. Vnoreni funguje perfektne. Protoze DO zvedne index a LOOP ho ubere. Ale co pak? Dalsi DO LOOP smycka by mela duplicitni index. Takze je jasne, ze index pro DO musi jen narustat. A u LOOP to zacne byt slozite. Prvni je jasny, je shodny s aktualnim DO, ale dalsi? Prvni nizsi cislo co uz nebylo pouzito. To chce nejaky zasobnik. Pochybuji ze M4 zvladne zasobnik. PS: To same plati pro IF THEN. PSS: Mozna bych se na to mel vykaslat a napsat to cele v C, nemusel bych resit jak se to dela, nebo zda to vubec jde udelat v jinem nastroji. |
Autor: | _dworkin [ 14.05.2020, 12:19 ] | ||
Předmět příspěvku: | Re: Macro FORTH | ||
M4 ma zasobnik! Viz fotka, dokonce dvojity (i trojity)! Jak jsem mohl byt maloverny. Kód: define(LOOP_COUNT,100)dnl
dnl define(NEWLABEL,`$1$2$3')dnl dnl define(DO, ` define(`LOOP_COUNT', incr(LOOP_COUNT)) pushdef(`LOOP_STACK', NEWLABEL( do, LOOP_COUNT)) PUSH HL ; 1:11 index PUSH DE ; 1:11 stop EXX ; 1:4 POP DE ; 1:10 stop DEC HL ; 1:6 LD (HL),D ; 1:7 DEC L ; 1:4 LD (HL),E ; 1:7 stop POP DE ; 1:10 index DEC HL ; 1:6 LD (HL),D ; 1:7 DEC L ; 1:4 LD (HL),E ; 1:7 index EXX ; 1:4 POP HL ; 1:10 POP DE ; 1:10 LOOP_STACK:')dnl dnl define(UNLOOP, ` EXX INC L ; 1:4 INC HL ; 1:6 INC L ; 1:4 INC HL ; 1:6 EXX')dnl dnl define(LOOP, ` EXX LD E,(HL) ; 1:7 INC L ; 1:4 LD D,(HL) ; 1:7 DE = index INC HL ; 1:6 LD A,(HL) ; 1:7 SCF ; 1:4 SBC A, E ; 1:4 stop_lo - index_lo - 1 INC L ; 1:4 LD A,(HL) ; 1:7 BC = stop SBC A, D ; 1:4 stop_hi - index_hi - 1 JR c, $+12 ; 2:7/12 exit INC DE ; 1:6 index + 1 DEC L ; 1:4 DEC HL ; 1:6 LD (HL), D ; 1:7 DEC L ; 1:4 LD (HL), E ; 1:7 EXX ; 1:4 JP LOOP_STACK ; 3:10 INC HL ; 1:6 EXX popdef(`LOOP_STACK')')dnl dnl define(` EXX EXX',;---)dnl proc to nefunguje? // ------ DO DO DO UNLOOP LOOP LOOP DO LOOP LOOP
|
Stránka 1 z 40 | Všechny časy jsou v UTC + 1 hodina [ Letní čas ] |
Powered by phpBB® Forum Software © phpBB Group http://www.phpbb.com/ |