Busy píše:
_dworkin píše:
Busy píše:
Ako by si tymto sposobom (tou tabulkou pre doplnenie doprednych adries) riesil napriklad nieco taketo ?
Kód:
ld h,high table / 2
ld l,low table + 5
...
table: db 1,2,3
generuje se kod pro LD D,xx
0x16 0x00
s tim ze do se ulozi do nejake tabulky ze na ORG+1 se ma zapsat BAJT zjisteny z vyrazu high table/2
generuje se kod pro LD L,xx
0x2E 0x00
s tim ze do tabulky se ulozi ze na ORG+1 se ma zapsat BAJT zjisteny z vyrazu low table+5
nastavi se promena table na ORG+4
generuje se
0x01 0x02 0x03
Takze mame kod
0x16 0x00 0x2E 0x00 0x01 0x02 0x03
a zname hodnotu table = Org+4
Koukneme se na resty do "tabulky"
Prvni je vyraz "high table/2" to uz umime spocitat a vime kam to zapsat ze je to bajt
Takze mame kod
0x16 0x?? 0x2E 0x00 0x01 0x02 0x03
Druhy je vyraz "low table+5" to uz umime spocitat na Org+9 a vime kam to zapsat ze je to bajt
Takze mame kod
0x16 0x?? 0x2E 0x?? 0x01 0x02 0x03
Jeden pruchod s pomocnou tabulkou?
Fuuuuuuuuuu a nepride ti to zbytocne zlozite ? Pre kazdu jednu doprednu referenciu si musis pametat polozku v tabulke dynamickej velkosti (t.j. zretazeny zoznam struktur), ktora musi obsahovat offset kde v kode sa dany udaj nachadza, informaciu o sirke tohto udaja a (potencialne velmi zlozity) vyraz na jeho vyhodnotenie. Musis spravit jeden kompilacny prechod, a potom specialnou osobitnou rutinkou prechadzat tuto tabulku, vyhodnocovat vyrazy a doplnat data.
Nemyslis, ze je vazne jednoduchsie proste ten kompilacny prechod spustit 2x a nekomplikovat si zivot tou osobitnou specialnou rutinkou ? Kod kompilera bude jednoduchsi a voci tvojmu rieseniu to ma same vyhody (napr. nizsia pravdepodobnost skryteho bugu)
Uvedom si, ze kompiler nie je demo/intro, kde musi ten kod byt vymazleny aby bol maximalne rychly/kratky/efektivny. Kompiler je normalna aplikacia kde rychlost kompilacie a efektivita nie su az tak smerodatne.
Ptal ses me jak by to slo udelat jednim pruchodem, tak jsem ti to popsal.
Tabulka ani neni nutna, protoze kdyz budes znat tu hodnotu, tak stejne budes muset mit nejakou funkci/kod co to vykona, spocita a ulozi.
Takze to vnitrne muze byt delane jakymkoliv jinym zpusobem, kdyz narazi na neznamou hodnotu.
Muze pozdrzet/preskocit vykonani a pokracovat dal a pak se k tomu vratit pozdeji a dokoncit to.
Busy píše:
Ale aj keby sme pripustili ze by sa ti chcelo pisat tu osobitnu rutinku, tak skus tvojim jednoprechodovym sposobom prelozit tento kod:
Kód:
org #10000-dlzka
zaciatok:
...nejaka zlozita rutinka s tabulkami a absolutnymi skokmi...
dlzka = $-zaciatok
Pointa je, ze chcem aby bol kod umiestneny co najvyssie ako sa len da, t.j. aby KONCIL presne na konci pameti.
A v cem je problem?
Timhle jen udelas vsechny adresy nezname, zadny jiny rozdil tam nevidim.
Takze by se to vyresilo stejnym zpusobem jako predchozi priklad, jen by to zabralo vic pameti.
Jeden (a pul) pruchodovy zpusob je mozny i kdyz budes prasit a delat neobvykle scenare.
A scenar ktery to nezvladne, kdy je potreba 100 pruchodu, nezvladne ani pasmo ani sjasmplus. Pasmo to pozna a napise ti chybu, kdyz se mu hodnoty labelu budou prilis hybat.
Dokonce me prijde snazsi delat 100x zmeny nad tabulkou nez celym souborem. Zvlast kdyz se ti ta tabulka muze vlezt cela do pameti a soubor uz ne.
Busy píše:
_dworkin píše:
Umi sjasmplus mazat labely? Pokud umi exist a kdyby umel mazat labely tak by to slo resit jinak.
Mazat labely ? Naco ??? V zivote som take nieco nepotreboval. Pasmo to azda vie ?!?!
Pasmo to neumi, pasmo to ani nepotrebuje protoze umi udelat binarku nebo tapku bez toho ze bys mu rekl jakou ma mit delku.
Nevim proc do toho tahas pasmo, kdyz jsem se ptal na sjasmplus. .)
Kdyby sjasmplus umel smazat label, tak by to zkratilo o dost ty makra, protoze by odpadl problem s tim ze musim vytvaret pokazde jedinecny nazev, abych se vyhnul problemu ze $ bude interpretovano jako retezec a ne hodnota.
Kód:
if exist label_id
delete label_id
endif
label_id equ xxx
define moje_promena xxx
a pak me uz problem s $ nemusi zajimat.
Asi by to slo udelat bez mazani pomoci lokalnich nazvu, kdybych vedel jak na to. V pasmu je to celkem slozite a nepohodlne.
Protoze to tvoreni jedinecnych nazvu nefunguje pri --synatax=s, s tim to neumi slozit dve slova do jednoho.
Mozna by mohlo byt hezke reseni i
define moje_promnena equ xxx
kde by to equ znamenalo ze ma udelat "eval" toho xxx, bez toho ze bych vubec musel mit jmeno labelu.
Busy píše:
_dworkin píše:
PPS:
https://pasmo.speccy.org/pasmodoc.html znovu precteno a zminku o promennych jsem nenasel. Mas jiny manual? V tom odkaze neni ani jeden vyskyt slova "variable"
Ano, presne tento manual pouzivam aj ja.
A je to tam. Sice nie priamo slovo variable (to som ani nesluboval ze tam bude), ale je tam popisane nieco, co sa ako premenna da pouzit. Pokial si to precital a nenasiel si to, necital si dost pozorne
Ak by sa ti to ani na druhy pokus nepodarilo najst, prezradim ti to klucove slovo, ktore treba hladat.
Inak v manuali k SjASMPlus sice slovo "variable" je, ale nie je to ono co hladas.
Cetl jsem to za ty roky vickrat a povazuji to za celkem neuzitecne a minimalisticke a pro pochopeni musis hledat nekde zdrojaky a jak to delaji jini. Protoze je k tomu spis potreba znalost jak to delaji jine prekladace, takze pak asi autorovi prislo ze to nema cenu vysvetlovat a jen napise ze to umi tohle, ne co to dela.
Myslim ze me precenujes ja to tam nevidim, zvlast kdyz ani neumim spanelsky ani anglicky.
Ale mozna narazis na DEFL.
Ok, mas pravdu defl dokaze premazet predchozi hodnotu, takze nepotrebujes undefine a je to zpusob jak pouzivat label jako promennou.
Takze pasmo umi tak poznat minimalni a maximalni pouzitou adresu.
A s tim rozidlem ze pasmo nedokaze predefinovat org na makro a neumi vypsat cislo (ani retezec pokud je to v promenne), bez toho ze by se clovek skrabal levou rukou za pravym uchem.
Kód:
macro print_hex_rep, print_hex_rep_a
if ( print_hex_rep_a )
print_hex_rep ((0xFFFF &(print_hex_rep_a))>>4)
if ((print_hex_rep_a) & 8)
if ((print_hex_rep_a) & 4)
if ((print_hex_rep_a) & 2)
if ((print_hex_rep_a) & 1)
.warning " ..F ; =1111"
else
.warning " ..E ; =1110"
endif
else ; 110.
if ((print_hex_rep_a) & 1)
.warning " ..D ; =1101"
else
.warning " ..C ; =1100"
endif
endif
else ; 10..
if ((print_hex_rep_a) & 2)
if ((print_hex_rep_a) & 1)
.warning " ..B ; =1011"
else
.warning " ..A ; =1010"
endif
else ; 100.
if ((print_hex_rep_a) & 1)
.warning " ..9 ; =1001"
else
.warning " ..8 ; =1000"
endif
endif
endif
else
if ((print_hex_rep_a) & 4)
if ((print_hex_rep_a) & 2)
if ((print_hex_rep_a) & 1)
.warning " ..7 ; =0111"
else
.warning " ..6 ; =0110"
endif
else ; 010.
if ((print_hex_rep_a) & 1)
.warning " ..5 ; =0101"
else
.warning " ..4 ; =0100"
endif
endif
else ; 00..
if ((print_hex_rep_a) & 2)
if ((print_hex_rep_a) & 1)
.warning " ..3 ; =0011"
else
.warning " ..2 ; =0010"
endif
else ; 000.
if ((print_hex_rep_a) & 1)
.warning " ..1 ; =0001"
else
.warning " ..0 ; =0000"
endif
endif
endif
endif
endif
endm
macro print_hex, print_hex_a
.warning "0x.."
print_hex_rep print_hex_a
endm
Tisk jako binarni cislo je o neco kratsi, ale zato vypis delsi...
Kód:
macro print_bin_rep, print_bin_rep_a
if ( print_bin_rep_a )
print_bin_rep ((0xFFFF &(print_bin_rep_a))>>2)
if ((print_bin_rep_a) & 1)
if ((print_bin_rep_a) & 2)
.warning " 11"
else
.warning " 10"
endif
else
if ((print_bin_rep_a) & 2)
.warning " 10"
else
.warning " 00"
endif
endif
endif
endm
macro print_bin, print_bin_a
.warning "bin number:"
print_bin_rep print_bin_a
endm
A to reseni pro pasmo vypada takhle:
Kód:
ifdef __ORG
org __ORG
else
org 0x8000
endif
include print_hex_value.asm
macro check_min, check_min_a
ifdef org_min
if org_min > check_min_a
org_min defl check_min_a
endif
else
org_min defl check_min_a
endif
endm
macro check_max, check_max_a
ifdef org_max
if $ > org_max
org_max defl $
endif
else
org_max defl check_max_a
endif
endm
macro my_org, my_org_a
ifdef org_now
if org_now != $
check_min org_now
check_max $
endif
endif
org_now defl my_org_a
; musi byt az na konci kvuli tomu ze parametr muze byt "$-value" a pak by org_now=($-value)-value
org my_org_a
endm
my_org $
dw 0x0000 ; org_min is still undefined
dw 0x0001 ; org_max is still undefined
dw 0x0002 ;
dw 0x0003 ;
my_org $-12 ;
dw org_min ; 0x7FFC = min = 0x7FFC
dw org_max ; 0x7FFE = max = 0x8008
my_org 0x4000
my_org 0x9000
my_org 0x8008
dw org_min ; 0x8008 = min
dw org_max ; 0x800A = max
my_org $ ; 0x800C
print_hex org_min
print_hex org_max
print_hex org_max-org_min
To je o dost kratsi a prehlednejsi nez co jsem vypotil pro sjasmplus.
Vystup je:
Kód:
dworkin@dw-A15:~/Programovani/ZX/Forth/Sjasmplus_test$ pasmo org_min_max.asm smaz.bin
WARNING: "0x.." on line 70 of file print_hex_value.asm
WARNING: " ..7 ; =0111" on line 38 of file print_hex_value.asm
WARNING: " ..F ; =1111" on line 8 of file print_hex_value.asm
WARNING: " ..F ; =1111" on line 8 of file print_hex_value.asm
WARNING: " ..C ; =1100" on line 16 of file print_hex_value.asm
WARNING: "0x.." on line 70 of file print_hex_value.asm
WARNING: " ..8 ; =1000" on line 30 of file print_hex_value.asm
WARNING: " ..0 ; =0000" on line 60 of file print_hex_value.asm
WARNING: " ..0 ; =0000" on line 60 of file print_hex_value.asm
WARNING: " ..C ; =1100" on line 16 of file print_hex_value.asm
WARNING: "0x.." on line 70 of file print_hex_value.asm
WARNING: " ..1 ; =0001" on line 58 of file print_hex_value.asm
WARNING: " ..0 ; =0000" on line 60 of file print_hex_value.asm
WARNING: "0x.." on line 70 of file print_hex_value.asm
WARNING: " ..7 ; =0111" on line 38 of file print_hex_value.asm
WARNING: " ..F ; =1111" on line 8 of file print_hex_value.asm
WARNING: " ..F ; =1111" on line 8 of file print_hex_value.asm
WARNING: " ..C ; =1100" on line 16 of file print_hex_value.asm
WARNING: "0x.." on line 70 of file print_hex_value.asm
WARNING: " ..8 ; =1000" on line 30 of file print_hex_value.asm
WARNING: " ..0 ; =0000" on line 60 of file print_hex_value.asm
WARNING: " ..0 ; =0000" on line 60 of file print_hex_value.asm
WARNING: " ..C ; =1100" on line 16 of file print_hex_value.asm
WARNING: "0x.." on line 70 of file print_hex_value.asm
WARNING: " ..1 ; =0001" on line 58 of file print_hex_value.asm
WARNING: " ..0 ; =0000" on line 60 of file print_hex_value.asm
dworkin@dw-A15:~/Programovani/ZX/Forth/Sjasmplus_test$ xxd smaz.bin
00000000: 0080 0880 0000 0100 0200 0300 fc7f 0880 ................
Tak a ted se jeste teda podivat zda je "DEFL" bezne mezi assemblery a sjasmplus to podporuje a zda je podpora obdobna a tohle reseni lze prevest na sjasmplus a tim se vyhnout potrebe umet mazat labely a tomu ze $ je jen znak dele nez je potreba.
Tak zda se ze to jde!
Musi se umazat carky v parametrech a zamenit IFDEF za IF EXIST a my_org lze nahradit primo za ORG
Kód:
ifdef __ORG
org __ORG
else
org 0x8000
endif
macro print_hex print_hex_a
display "val: ", /H, print_hex_a
endm
macro check_min check_min_a
if exist org_min
if org_min > check_min_a
org_min defl check_min_a
endif
else
org_min defl check_min_a
endif
endm
macro check_max check_max_a
if exist org_max
if $ > org_max
org_max defl $
endif
else
org_max defl check_max_a
endif
endm
macro ORG org_a
if exist org_now
if org_now != $
check_min org_now
check_max $
endif
endif
org_now defl org_a
; musi byt az na konci kvuli tomu ze parametr muze byt "$-value" a pak by org_now=($-value)-value
org org_a
display "...org_min: ", /H, org_min
display "...org_max: ", /H, org_max
display "... size: ", /D, org_max-org_min
endm
ORG $
dw 0x0000 ; org_min is still undefined
dw 0x0001 ; org_max is still undefined
dw 0x0002 ;
dw 0x0003 ;
ORG $-12 ;
dw org_min ; 0x7FFC = min = 0x7FFC
dw org_max ; 0x7FFE = max = 0x8008
ORG 0x4000
ORG 0x9000
ORG 0x8008
dw org_min ; 0x8008 = min
dw org_max ; 0x800A = max
ORG $ ; 0x800C
display "org_min: ", /H, org_min
display "org_max: ", /H, org_max
display " size: ", /D, org_max-org_min
device ZXSPECTRUM48
savebin "smaz.bin",org_min,org_max-org_min
S vystupem:
Kód:
dworkin@dw-A15:~/Programovani/ZX/Forth/Sjasmplus_test$ sjasmplus org_min_max_sjasmplus.asm
SjASMPlus Z80 Cross-Assembler v1.20.1 (https://github.com/z00m128/sjasmplus)
Pass 1 complete (0 errors)
Pass 2 complete (0 errors)
> ...org_min: 0x7FFC
> ...org_max: 0x800C
> ... size: 16
> ...org_min: 0x7FFC
> ...org_max: 0x800C
> ... size: 16
> ...org_min: 0x7FFC
> ...org_max: 0x800C
> ... size: 16
> ...org_min: 0x7FFC
> ...org_max: 0x800C
> ... size: 16
> ...org_min: 0x7FFC
> ...org_max: 0x800C
> ... size: 16
> ...org_min: 0x7FFC
> ...org_max: 0x800C
> ... size: 16
> org_min: 0x7FFC
> org_max: 0x800C
> size: 16
Pass 3 complete
Errors: 0, warnings: 0, compiled: 195 lines, work time: 0.003 seconds
dworkin@dw-A15:~/Programovani/ZX/Forth/Sjasmplus_test$ xxd smaz.bin
00000000: fc7f 0c80 0000 0100 0200 0300 fc7f 0c80 ................
Vystup je od PASMA rozdilny!!! Tady je videt ze sjasmplus s tim zachazi proste jinak... vypada to ze na rozdil od pasma drzi label jako "text" do posledni chvile...
Protoze obsahuje konecnou hodnotu v celem prubehu vypoctu na rozdil od pasma, to proste kdyz narazi na label tak preda jeho hodnotu a ne retezec s jeho nazvem.
Nastesti to nemusi vadit, protoze jde jen o vysledek a nazev toho labelu by mel byt pro programatora "skryty", ani by nemel vedet ze existuje...
Cele by to slo zjednodusit pridanim neceho jako init_org s tim ze by se tam definovaly org_min, org_max a org_now na pocatecni hodnoty.
Takze by se vynechali vsechny ty "ifdef" (pasmo) nebo "if exist" (sjasmplus).
Ale predpokladalo by to ze neprasis kod a neni to neco jako
org 0x8000
org_init
; nejake komentare ale nic se nezapise...
org 0x9000
normalni kod
koec programu
protoze pak by bylo spravne inicializovat pouze org_now
Takze dneska budu moct zase aktualizovat M4 FORTH a vylepsit/zjednodusit podporu pro sjasmplus. To je pozitivni vysledek tohohle snazeni.
Busy píše:
_dworkin píše:
PPPS: Pisou tam dokonce ze Pasmo dela vic pruchodu jak jsem psal, pisi o tretim kdyz zjisti zmenu v adresach. Vlastne nevim na co si temi dvema pruchody reagoval.
Prechodov moze samozrejme by viac. Aj SjASMPlus ich robi viac ako dva. Reagoval som na to ze si ani netusil, ze Pasmo robi viac prechodov
Aha tak to si spatne pochopil, protoze vim ze ma Pasmo vic pruchodu, muzes si vyhledat ty prispevky kde se divim ze pri -d tedy toho co dela --list u sjasmplus se divim ze ze tam ma ten kod vickrat, to byl ten moment kdy jsem to zjistil.