Diskuze o textových hrách

Tvorba Textových her => Programování => Téma založeno: zxretrosoft 27. Červen 2010 - 11:05

Název: Assembler z80
Přispěvatel: zxretrosoft 27. Červen 2010 - 11:05
Neumí tady někdo programovat (alespoň trochu) v assembleru Z80?

Rád bych se to naučil, ale pořád mi něco uniká... Stáhl jsem si Bity do bytu od L. Zajíčka, velice srozumitelná věc, ale zasekl jsem se v 2. části instrukčního souboru, přes který se nemůžu prokousat  ???

Nejradši jsem dosud používal překladač Prometheus od Proximy, ale začal jsem si postupně teď zvykat na velice přehledný a pohodlný zabudovaný editor přímo v emulátoru EmuZWin.

Mám taky pocit, že mi chybí dost kratších ukázek, abych si to mohl lépe osahat...  ::)

Zkrátka, neumí to někdo, aby mi s tím pomohl? Potřeboval bych se na několik konkrétnách věcí přeptat, případně to ještě nějak prokonzultovat a prohloubit si znalosti  8)
Název: Re: Assembler z80
Přispěvatel: KaiN 28. Červen 2010 - 08:55
Snad bych si ještě na něco mohl vzpomenout. Zajíček je super, sám jsem se to podle toho učil. Ještě snad někde v krabici ve sklepě mám tuhle a pár jiných knížek. Naprogramoval jsem v tom před mnoha a mnoha lety jednu celou hru - potápěč, poklad, chobotnice; podle nějaké ruské elektronické hry, a několik blbostí, jako např. rutinu pro psaní 42 písmen na řádek namísto 32 apod.
Název: Re: Assembler z80
Přispěvatel: zxretrosoft 28. Červen 2010 - 10:05
Perfektní!  ;) - a nemáš náhodou zkušenosti s tím EmuZWin ? Mně totiž přijde zbytečný mastit to v dnešní době v Prometheovi (i když je super a předběhl dobu), když EmuZWin má tak pohodlný assembler editor přímo v sobě. Jenže nějak ho moc nechápu - když tam napíšu program, dám zkompilovat, nic se nestane...?  ::)
Název: Re: Assembler z80
Přispěvatel: KaiN 28. Červen 2010 - 11:08
Prometheus jsem nepoužíval.  :) Papír, tužku a GENS 3 a MONS 3 od HiSoft.  ;) Ještě jeden prográmek, něco jako Assembler Tutorial, v tom jsem zpočátku zkoušel krátký rutinky, šlo to dobře trasovat, ukazovalo to stavy registrů atd. EmuZWin jsem nezkoušel, ale nemusí se tam dát startovací adresa, aby to bylo spustitelné?
Název: Re: Assembler z80
Přispěvatel: zxretrosoft 28. Červen 2010 - 11:21
jj, na tu startovací adresu jsem myslel - jenže pokud ji tam dám ve tvaru např. org 25000 (jako se zadávala v Prometheovi), nic se nestane i po kompilaci ani po pokusu o spuštění přes BASIC. Na to se musí nějak přijít - ten editor je fakt příjemný...  ???
Název: Re: Assembler z80
Přispěvatel: KaiN 30. Červen 2010 - 13:36
Stáhnul jsem si to, tak to doma vyzkouším a dám vědět, zda a na co jsem přišel.
Název: Re: Assembler z80
Přispěvatel: zxretrosoft 30. Červen 2010 - 18:41
Díky předem!  ;)

Možná si zvyknu na ten Prometheus, ale přece jen bych radši něco modernějšího přímo na PC, vždyť - proč se trápit na ZX Spectru, když existují emulátory  ;D (I když uznávám, že trápit se na ZX Spectru má hodně co do sebe a je to svým způsobem nepřekonatelné  ;) )
Název: Re: Assembler z80
Přispěvatel: KaiN 1. Červenec 2010 - 13:47
Jo, čekat 4 minuty, až se to nahraje, a pak si přečíst "Tape loading error", to je nepřekonatelné. :)

Ale jinak jsem tomu nějak neporozumněl, vždyť toho Promethea si můžeš pustit na emulátoru na PC, ne?
Název: Re: Assembler z80
Přispěvatel: zxretrosoft 1. Červenec 2010 - 20:56
jj, Promethea samozřejmě můžeš spustit na emulátoru, ale myslel jsem něco takového "pohodlnějšího" jako je to u dnešních editorů vyšších jazyků (např. BASIN pro Basic ap.).

Ale to je jedno, s Prometheem mám stejně nějaké problémky, přes které se ne a ne přenést...

Takže jak vidno, je toho víc, proč nepoužít Promethea, ačkoli mám nejlepší vůli ho použít - tyhle 3 problémky bych zkrátka k úspěšnému používání Promethea potřeboval odstranit  ::)
Název: Re: Assembler z80
Přispěvatel: KaiN 2. Červenec 2010 - 08:10
Tak jsem ten EmuZWin vyzkoušel a řekl bych, že celý vtip je v tom, že on to kompiluje přímo do paměti RAM, takže spouštět to musíš (jakoby) z BASICu jako u klasického ZX. Napsal jsem tenhle "prográmek", který změní okraj obrazovky na černou barvu:

Kód: [Vybrat]
org 30000
xor a
out (254),a
ret

Když to zkompiluješ a následně v emulovaném ZX napíšeš např. RANDOMIZE USR 30000, tak se to spustí. No, takže soudím, že uložit to budeš muset taky z BASICu, myslím, že to je takhle: SAVE „nazev“ CODE 30000, délka kodu.

Přijde mi to velmi nepraktické.
Název: Re: Assembler z80
Přispěvatel: zxretrosoft 2. Červenec 2010 - 09:00
Jo, díky, opravdu to funguje!  :)

Mně to nepřijde tak nepraktické, ale to je asi proto, že jsem na ničem jiném nijak nedělal... Jak bych to samé udělal v Prometheovi? Pokud ho nemáš, mohl bych ti ho poslat, ale nevim, jestli nemám nějakou špatnou verzi, protože se mi skutečně některé instrukce neukazují  :-\ Např. ent $ nebo org 30000 tam nedostanu.
Název: Re: Assembler z80
Přispěvatel: KaiN 2. Červenec 2010 - 09:45
Možná bude mít Prometheus pro zadání startovací adresy jiný příkaz než org. Poslat mi to můžeš, ale bez manuálu ty případné odlišné příkazy kompilátoru nezjistíme. Mail: Petr.Kain(zavináč)seznam.cz.
Název: Re: Assembler z80
Přispěvatel: zxretrosoft 2. Červenec 2010 - 15:20
jj, právě že org xxxxx a ent $ by používat měl, ale mně se to tam ne a ne zobrazit...  ???

Pošlu ti tedy ten Prometheus + manuál k němu na e-mail.
Název: Re: Assembler z80
Přispěvatel: zxretrosoft 5. Červenec 2010 - 14:54
Tak jsem konečně získal funkční verzi Promethea - ten můj byl opravdu poškozený, proto vykazoval takové zvláštní chování...

Takže jdu experimentovat!  ;) A podám zprávu...  8)

P.S. Jo, a ten org tam fakt nemá být, klasicky s ent $ a pak kód, startovací adresa se zadává před spuštěním... Ačkoliv by měl Prometheus org standartně umět, ale jak říkám, teprve zkouším, tak uvidíme...
Název: Re: Assembler z80
Přispěvatel: zxretrosoft 5. Červenec 2010 - 19:00
Takže, pokusím se shrnout některé své první dojmy z programování v assembleru Z80 - možná ze sebe udělám totálního blbce, ale i za tu cenu budu rád, pokud se mi moje otázky někdo pokusí s trpělivostí vysvětlit  ::)

Přepsal jsem si z pěkné knihy Assembler a ZX Spectrum jeden z prvních příkladů a zdá se mi, že jsem buď nic nepochopil, nebo že to autor dostatečně nevysvětluje a nemám to ani z čeho pochopit. Obojí je možné, takže posuďte sami. Ať tak nebo tak mi jistě pomůže každá konstruktivní odpověď.

V příloze přikládám co by to mělo dělat - vytiskne se na obrazovku vlevo odshora pole 8x8 stejných znaků v různé barvě s různým podkladem.

Opisuji z knihy i s vysvětlivkami:

Kód: [Vybrat]
ent $ ;místo pro spuštění
START call #D6B ;podprogram pro CLS
ld a,2 ;číslo kanálu do registru A
call #1601 ;zavolání podprogramu
ld c,8 ;8 řádků
LOOP ld b,8 ;8 sloupců
LOOP2 ld a,22 ;nastavení tiskové pozice
rst 16
ld a,c
rst 16
ld a,b
rst 16
ld a,16 ;nastavení barvy inkoustu
rst 16
ld a,b
dec a
rst 16
ld a,17 ;nastavení barvy papíru
rst 16
ld a,c
dec a
rst 16
ld a,"@" ;vystiskni znak @
rst 16
djnz LOOP2 ;vnitřní cyklus
dec c ;zmenši C o jedničku
jr nz,LOOP ;vnější cyklus
ret ;po skončení návrat

A nyní k mojim skromným otázkám, kde přemýšlím spíš nahlas, abyste viděli jakým způsobem jsem se to pokusil dešifrovat:


Jak říkám, možná jsem úplný jelito, ale tohle je všechno, co jsem z toho příkladu jakžtakž dešifroval. Moc to - jak vidíte - stále nechápu. Celému tomu algoritmu rozumím tak, že něco připraví (síť toho, kde co bude a jaké to bude mít parametry) a pak to tam reálně vloží.
Možná by mi pomohl třeba i vývojový diagram - umí ho k tomu někdo jednoduše nakreslit? Mělo by to vůbec smysl pro pochopení tohodle příkládku?  ::)

Za každou radu předem děkuji!!  ;)
Název: Re: Assembler z80
Přispěvatel: Lisiak4 6. Červenec 2010 - 22:22
Ahoj,

Vše co napíšu může být blbost, nejsem v pozici, kdy můžu radit. Ja se jen tak ze zajímavosti trochu koukal na assembler procesoru MHB8080A co je kopie Intelu 8080A a Z80 je vylepšená 8080ka viz info z wikipedie. Zilog Z80 je osmibitový mikroprocesor, který vyráběla firma Zilog od roku 1976. Jednalo se o funkční zdokonalení procesoru Intel 8080. Struktura registrů i instrukční sada vycházely z architektury procesoru Intel 8080 a až na drobnosti byly zpětně kompatibilní. V tabulce instrukci pro 8080ku se píše:

A - akumulátor
B - register B alebo registrový pár BC
C - register C
D - register D alebo registrový pár DE
E - register E
H - register H alebo registrový pár HL
L - register L

Tím narážím na to, že se tváří, jakoby A jak ty píšeš registr, zde se píše Akumulátor nebylo to samé jako B,C,D,E,H,L
Podprogram v pameti RAM pro počítač PMD používa Akumulátor na vyťištení znaku. Nevím, jestli tuhle funkci múže dělat i register B,C .... proto je tam možna to přesouvání, ale jsou to jen domněnky. Snažím se jen pomoci, jak tomu jako absolutní amatér koukajíci do toho asi 5 dní rozumím já. Další můj postřeh (možná mylnej) je ten, že v Assemblery se používa dle mě jen hexadecimálni soustava. Tím narážím na to, že například číslo 22 by sme neměli chápat jako 22 ale po přepočítání z hexadecimální soustavy nám to dá číslo 34. Jak říkam, vše co jsem napsal může být úplně špatně. Jsou to názory někoho, kdo do toho vůbec nevidi, jen jsem se snažil aspoň nejak pomoci. Vyzkoušel si v Assembleru pomoci nějakeho podprogramu něco jednoduchýho, aby Ti to fungovalo? Například vypsáni jednoho znaku? A pak nejakýho textu? Tohle se mi zdá být nejak složité na začátek :). V návodu na PMD je pár ukázek na využívání podprogramu assembleru na PMD, podprogram pro psani znaku i textu. Neni něco takového v návodu pro ZX?
Název: Re: Assembler z80
Přispěvatel: zxretrosoft 7. Červenec 2010 - 11:11
Naopak, díky moc, tohle přesně potřebuju - člověka to hned nakopne k přemýšlení!  ;)

Pokud jde o ten akumulátor, mám za to, že akumulátor je zkrátka druh registru. Ano, stejně jako u PMD se registr A používá k vytištění znaku.
Hexadecimální soustava se používá v Prometheovi tak, že před číslo se dá znak #. Pokud je tedy číslo 22 uvedeno bez toho znaku, je to opravdu 22 v desítkové soustavě, muselo by být uvedeno jako #22.

Ta knížka je docela dobrá (asi nejlepší co mám k dispozici), ale taky mi připadá, že příklady na začátek jsou příliš složité a (viděno mýma očima laika) naprosto neprůhledné. Takové to šachování s registrama by chtělo nějak objasnit. Pokud mi někdo napíše, že nastavení barvy papíru je: ld a,c ... atd., pak musím vědět, proč zrovna obsah C přesouvá do A, k čemu je to dobré a proč se zrovna jako programátor musím rozhodnout, že obsah C přesunu do A. To přece není samo sebou - to musí mít nějaký důvod  :) Proto je spousta těch příkladů, které tento důvod neuvádějí, dost k ničemu, neboť je člověk (skoro jako vždy) odkázán na vlastní experimentování.

No, ale abych se vrátil k věci...

Znak jsem se pokusil vytisknout zjednodušeným algoritmem:

Kód: [Vybrat]
ent $
ld a,2
call #1601
ld a,"x"
rst 16
ret

Tenhle kód vytiskne znak "x" nahoru na obrazovku. Většina věcí v kódu se dělá automaticky: ent $ je startovací instrukce; ld a,2 se napsat musí pokaždý - do registru A musí přijít kanál 2, což supluje basicovský PRINT; call #1601 - o tom se zase nemusí přemýšlet, zkrátka zavolání podprogramu v ROM na adrese #1601=5633, aby se otevřel kanál a zobrazilo se to, co je obsahem A. Teď ale do toho registru A něco dáme a vystikneme pomocí rst 16, tedy ld a,"x" a rst 16. Nakonec jsem dal příkaz ret - nějak moc nevím sice proč, ale bez toho ret se to provede, ale nezůstane na obrazovce, takže je to asi věčná smyčka, která nám umožňuje vidět ten znak na obrazovce(?).

To je prosté vytištění jednoho znaku. Jednu věc na tom programu však nechápu - pokaždé, když se spustí, se vytištěný znak posune o 1 místo doprava, dojede-li na konec obrazovky, jede na další řádce zase zleva. Ačkoli není určená pozice, kvůli něčemu se to posouvá. A i kdybych věděl kvůli čemu, tak proč nezůstává "x" i na předchozím místě? Není zde ani CLS, a obsah registrů se v programu nikde nenuloval...?! Ale asi jsem vedle  :-\

Složitější případ jsem si vymyslel, když jsem chtěl umístit znak někam konkrétně na obrazovku (tedy jako v Basicu pomocí PRINT AT nebo LOCATE ... PRINT ap.).

K tomu by měl být funkční tehle kód:

Kód: [Vybrat]
ent$
ld a,2
call #1601
ld a,22
rst 16
ld a,14
rst 16
ld a,2
rst 16
ld a,"x"
rst 16
ret

Přibylo tu akorát na začátku ld a,22 - což by měl být podle knihy kód pro funkci AT, kde se nejprve zadává řádek a potom sloupec. Nevím ale pořád, proč za každým příkazem musím dělat rst 16 ? Když to vynechám, napíší se třeba před znak otazníky... Tím tedy docílím toho, že na řádek 2 a sloupec 16 dostanu znak "x".

Ještě si s tím zkusím pohrát, ale to je zatím všechno, co jsem z toho dostal - a ačkoli už se mi daří vytisknout znak, dokonce přesně ho lokalizovat a časem mu dát i jiné atributy, mám pocit, že je to všechno moc komplikované na to, že je to vlastně pořád to samé co v Basicu, akorát složitějším způsobem... Možná je to ale tím, že jsem úplně na začátku  ::)
Název: Re: Assembler z80
Přispěvatel: zxretrosoft 11. Červenec 2010 - 11:06
Tak myslím, že ta knížka Assembler a ZX Spectrum vypadá sice dobře, ale je pro daleko pokročilejší programátory. Snaží se sice hodně věcí objasnit od základu, ale příklady, které uvádí, jsou strašně komplikované a laik se v nich musí ztratit (mluvím za sebe, ale chtěl bych vidět, kdo by tohle na poprvé pochopil).

Když si vzpomenu na to, jak byly dělány ukázky v Basicu v každém časopise, tak přesně tak by měly být ukázky i z assembleru. To znamená: PRINT "x" udělá x na obrazovce, PRINT AT 1,1;"x" udělá na souřadnicích 1,1 x na obrazovce... Nikoliv: Tenhle program udělá x na obrazovce v šachovnici 8x8 podbarvené každý znak jinou barvou a to od 1 do 8 s barvou písma 1 do 8 invertovanou vůči barvě podkladu. Takový příklad je strašně složitý a když si představím, že bych ho udělal v Basicu, pak by to bylo taky dost složitý pro toho, kdo nikdy Basic neviděl.

To, co se udělalo tím příkladem s tiskem znaku, odpovídá přesně tomuto Basicovskému programu (v syntaktice ZX):

Kód: [Vybrat]
10 FOR i=0 to 7
20 PAPER i
30 FOR j=0 to 7
40 INK j
50 PRINT AT i,j;"@"
60 NEXT j
70 NEXT i

Posuďte sami, že to pro začátečníka není samozřejmé ani v tom Basicu - jsou to 2 cykly v sobě, změna barev i podkladu, představa jak to bude na obrazovce vyžaduje už určitý cvik...  :-\

V nějakém složitějším, moderním Basicu na PC (např. FreeBasicu), byste to už těžko dešifrovali - a to je pořád ještě Basic. Odpovídal by tomu řešení (alespoň zhruba) např. takovýhle prográmek:

Kód: [Vybrat]
dim as single i,j,k
screen 20,32,,0
cls
for i=0 to 7
for j=0 to 7
k=i*15
draw string$(j*10+16,i*10+16),"@",rgb(k,k+i*j*3,110)
next j
next i


Později jsem si zkoušel třeba i "jednoduchý" prográmek pro PLOT z téže knihy:

Kód: [Vybrat]
PLOT1 ld a,b
call #22B1
ld b,a
inc b
ld a,1
PLOT1A rrca
djnz PLOT1A
xor (hl)
ld (hl),a
ret

Tenhle prográmek udělá sice bod v jakési části obrazovky, pochybuji ale, že z toho vyčte někdo kde a proč. Instrukcí call #22B1 se má "vypočítat adresa a bit pro tento bod", to je sice hezké... ale...?? První nápad s instrukcí ld a,b je mi také nejasný - proč obsah registru B přesouvat do A, abych získal Y-ovou souřadnici? Jaká je tedy její hodnota? To co bylo v B? Ale kde jsem to B nastavil? Proč to nedat vlastně rovnou do A (tj. bez použití registru B, se kterým předtím stejně vůbec nepracuji)?...

Je toho víc, co mi přijde nepochopitelné, ale možná nejsem tak chytrý, nevím, těžko říct... Asi by mi pomohlo, kdyby existovalo víc jednodušších příkladů, které by byly ekvivalentní k Basicu - různé komplikovanosti a další možnosti už by si člověk experimentováním objevil. Ale chtělo by to zkrátka:

BASIC: PRINT AT 5,6;"x" -> ASSEMBLER: ld a,b ....
BASIC: BEEP 1,1 -> ASSEMBLER: ld a,b ....
BASIC: PLOT 100,20 -> ASSEMBLER: ld a,b ....

Jsem přesvědčen, že na neskonalé možnosti assembleru by si člověk musel přijít sám, stejně jako jsme si je odvodili tehdy z Basicu.

Co si o tom myslíte? Neznáte náhodou nějakou "lepší" knížku k assembleru? Bližší tomu, co jsem nastolil?  ::)
Název: Re: Assembler z80
Přispěvatel: KaiN 12. Červenec 2010 - 09:02
Ještě k tomu prvnímu příkladu, ono už to tu víceméně nějak bylo rozlousknuto, tak to jen shrnu:

Já myslím, že jediný tvůj problém je, že nemáš zmapován ten "rst 16". Parametr se předává výhradně v registru A, nejprve se předá "co" se bude dělat. Např. "22" znamená "PRINT AT x,y", následně se přes registr A předá "x" a poté i "y". Registry B a C se v prográmku používají jako počítadla. B je přitom jako počítadlo u Z80 předpokládáno, proto např. existuje instrukce DJNZ loop2, která nejprve sníží registr B a pokud je výsledek nenulový, provede skok na loop. U C je třeba nejprve samostatně snížit C (dec C) a poté samostatně vyhodnotit výsledek operace pomocí "JR NZ loop".
RET znamená obecně návrat tam, odkud byla rutina volána. Pokud ji vyvoláš přímo z BASICU, vrátí se po vykonání na následující řádek resp. příkaz.
Název: Re: Assembler z80
Přispěvatel: mop 27. Červenec 2010 - 21:50
Taky si myslím, že dokud nebudeš pořádně vědět, co dělá ta instrukce RST 16, tak ti tyhle příklady žádný užitek nepřinesou. Přiznám se, že považuju za docela nešťastný tenhle přístup k výuce assembleru, kdy se jako příklad použije kód, jehož podstatná část je tvořena instrukcemi CALL nebo RST, volajícími nějaké už existující rutiny v ROM nějakého konkrétního počítače. Z takového příkladu se v konečném důsledku stejně dopodrobna nedozvíš, co ten program vlastně vykonává.

Jestli trochu vládneš anglicky, tak rozhodně doporučuju tyhle stránky, kde na to autor jde přesně opačně:

http://sgate.emt.bme.hu/patai/publications/z80guide/ (http://sgate.emt.bme.hu/patai/publications/z80guide/)

Myslím, že je to výborné čtivo na úplný začátek, pro pochopení samotné filozofie strojového jazyka. Ale tím, že je to tutoriál naprosto obecný, který se nezabývá specifiky nějakého konkrétního počítače, nenajdeš v něm odpovědi na své otázky týkající se ZX Spectra (jako třeba právě otázka, co dělá ta instrukce RST 16).

Já jsem si kdysi dávno něco málo psal pro počítač Sharp, takže s věcmi specifickými pro ZX poradit neumím, ale s otázkami týkajícími se obecně strojáku Z80 se můžu pokusit pomoct. Ale nevím, jestli je to ještě aktuální, jelikož tady už dva týdny žádná diskuse neběží.
Název: Re: Assembler z80
Přispěvatel: zxretrosoft 27. Červenec 2010 - 22:00
jj, díky za odpověď! Určitě se na ty anglické stránky mrknu!  ;)

Aktuální to je pořád, akorát na programování nemám tolik času, je to přece jen moje zábava po práci, takže si tu a tam chci něco zkusit a něco pochopit. Assembler (alespoň na Z80) bych se rád naučil, ještě se do toho vrhnu a zkusím to s jiným tutoriálem.

V téhle diskuzi jsem se chtěl vlastně jen dopátrat, jak konkrétně zacházet s obrazovkou, v tomhle případě na začátek s textem, ale i když to v reálu nějak dokážu, nemůžu říct, že to chápu - a proto jsem tu diskuzi rozpoutal. Assembler Z80 se dnes člověk učí hlavně (či spíš jenom) kvůli tomu, aby to pochopil a měl z toho radost, ne proto, aby něco zplácal bezmyšlenkovitě dohromady (viz dnešní programování v C++ apod.  ;D ).

Každopádně ještě jednou díky za ten odkaz i odpověď, v nejbližší době se na to podrobněji podívám!  8)
Název: Re: Assembler z80
Přispěvatel: mop 28. Červenec 2010 - 10:57
Nedalo mi to a stáhnul jsem si v pdf 1. díl té knihy Assembler a ZX Spectrum, kde je na str. 36 vysvětleno, jak je to vlastně s tím RST 16:

Citace
... Tisk znaku je zajišťován instrukcí rst 16 (volání podprogramu na adrese 16). Znak, který má být vytisknut, je uložen v registru a. ... Program umí tisknout všechny ASCII znaky, semigrafiku, UDG, klíčová slova a zpracovávat tyto řídící kódy:
6 - print COMMA (posune na další pozici - začátek nebo polovina řádku)
8 - cursor left (posune tiskovou pozici doleva)
9 - cursor right (posune tiskovou pozici doprava)
10 - cursor down (posune tiskovou pozici dolů)
11 - cursor up (posune tiskovou pozici nahoru)
13 - ENTER (přesune tiskovou pozici na začátek dalšího řádku)
16 - ink (ovládání barvy inkoustu - pošlete kód 16 a potom číslo 0-7)
17 - paper (ovládání barvy papíru - pošlete kód 17 a potom číslo 0-7)
18 - flash (ovládání blikání - pošlete kód 18 a potom číslo 0 nebo 1)
19 - bright (ovládání jasu - pošlete kód 19 a potom číslo 0 nebo 1)
20 - inverse (ovládání inverze - pošlete kód 20 a potom číslo 0 nebo 1)
21 - over (ovládání over - pošlete kód 21 a potom číslo 0 nebo 1)
22 - at (nastavení tiskové pozice - pošlete kód 22 a potom řádek a sloupec)
23 - tab (tabulátor - pošlete kód 23 a potom číslo rozložené do dvou bytů)

To je naprosto v souladu se známým faktem, že v ASCII tabulce začínají tisknutelné znaky až od č. 32, zatímco hodnoty 0 až 31 bývají využívány pro různé užitečné úkony, jako je třeba tabulátor, enter apod. (proto tomu říkají řídicí kódy). Takže v zásadě se dá říct, že sekvence instrukcí LD A,x a RST 16 dělá totéž, co příkaz PRINT CHR$(x) v basicu. Zkus třeba do basicu naťukat tohle:

Kód: [Vybrat]
10 LET A$="AHOJ"+CHR$(13)+"SVETE"
20 LET B$="HELLO"+CHR$(22)+CHR$(5)+CHR$(20)+"WORLD"
30 PRINT A$
40 PRINT B$

Když se podíváš, co to dělá, a dáš si to dohromady tady s tím seznamem řídicích kódů, tak ti to podle mě pomůže pochopit i leccos z těch dřívějších příkladů v assembleru.
Název: Re: Assembler z80
Přispěvatel: zxretrosoft 28. Červenec 2010 - 19:44
Děkuju za ten příklad!  ;)

O tom "vysvětlení", jak je to s tím rst 16 jsem to četl, což o to, ale přece jen proč je umístěno rst 16 po každé instrukci, která odesílá nějaký údaj?

Např.:

Kód: [Vybrat]
ld a,22 'funkce AT
rst 16 '??
ld a,14 'číslo řádku
rst 16 '??
ld a,20 'číslo sloupce
rst 16 '??

Proč vlastně pořád volám tiskový podprogram?  ::)
A vůbec - nejde to nějak jednodušeji?  :)

Jen tak si představuji, že si zkouším něco s assemblerem - třeba náhodně na nějakou lokaci na obrazovce umístit barevnou hvězdičku. To mi při tomhle způsobu programování spolkne mnoho a mnoho instrukcí rst 16 ?  ::)
Název: Re: Assembler z80
Přispěvatel: mop 28. Červenec 2010 - 21:47
Ona ta instrukce LD A,x právě nikam nic neposílá. Ta jen nastaví registr A na nějakou hodnotu, a basta. A pak se teprve volá podprogram pro tisk znaku, který udělá všechnu práci a který je napsán tak, že hodnotu požadovaného znaku si bere právě z registru A.

Pokud jde o ty příklady, tak tam je to takhle mechanicky za sebou jen kvůli lepší přehlednosti. V reálu budeš mít ty data uložený někde v paměti hezky za sebou a jejich tisk bude řešený nějakým cyklem, takže ta instrukce bude v kódu napsaná jen jednou, i když budeš vypisovat dlouhé řetězce, různýma barvičkama atd.
Název: Re: Assembler z80
Přispěvatel: zxretrosoft 28. Červenec 2010 - 22:03
Aha, dobře, díky moc, ještě si s tím zkusím pohrát!...  ;)
Název: Re: Assembler z80
Přispěvatel: zxretrosoft 4. Srpen 2010 - 22:25
Ona ta instrukce LD A,x právě nikam nic neposílá. Ta jen nastaví registr A na nějakou hodnotu, a basta. A pak se teprve volá podprogram pro tisk znaku, který udělá všechnu práci a který je napsán tak, že hodnotu požadovaného znaku si bere právě z registru A.

Pokud jde o ty příklady, tak tam je to takhle mechanicky za sebou jen kvůli lepší přehlednosti. V reálu budeš mít ty data uložený někde v paměti hezky za sebou a jejich tisk bude řešený nějakým cyklem, takže ta instrukce bude v kódu napsaná jen jednou, i když budeš vypisovat dlouhé řetězce, různýma barvičkama atd.

Dobře, tak ještě mě napadlo všechno moje snažení zjednodušit a směřovat to rovnou k nějaké té textovce...  :D

V Prometheovi jdou texty vypisovat pomocí defm, jestli jsem to dobře pochopil (podle Assembler a ZX Spectrum je to teda trochu kumšt). Kdybych chtěl udělat nějaký jednoduchý skok, který je v textovkách obvyklý, např.


Dal by se tenhle proces co nejvíce zjednodušit? V zásadě na tom by mohla stát totiž každá textovka  :) Ale je to pro mě pořád proces, který neumím udělat. Možná už chci moc, ale aspoň jeden bod z toho bych rád zrealizoval co nejjednodušším způsobem, v nejlepším případě všechny 3 body  ::)

V Basicu je to samozřejmě triviální:

Kód: [Vybrat]
10 PRINT "Jsi na křižovatce. Jakým směrem půjdeš?"
20 INPUT x$
30 IF x="S" THEN GOTO 50 ELSE GOTO 40
40 PRINT "Tam se jít nedá." : GOTO 10
50 PRINT "Jsi na severní křižovatce."

Pak bych zkusil pokračovat (např. tomu dát nějakou barvu, efekty, zvuk...), ale to už je hudba budoucnosti. Zatím bude stačit zrealizovat tohle  ???
Název: Re: Assembler z80
Přispěvatel: KaiN 5. Srpen 2010 - 08:42
Ajaj, takhle snad raději ne. ;) Mimochodem, řekl bych, že ti to ani nebude fungovet. Podle mě tam má být "INPUT x$". Jestli chceš mermomocí udělat textovku pro ZX, použij PAW nebo Quill (viz. WoS), když nebudeš vymýšlet nějaké komplikované příkazy, tak to s "cestinou" půjde. Sám jsem to kdysi dávno zkoušel.
Název: Re: Assembler z80
Přispěvatel: zxretrosoft 5. Srpen 2010 - 09:12
Ajaj, takhle snad raději ne. ;) Mimochodem, řekl bych, že ti to ani nebude fungovet. Podle mě tam má být "INPUT x$". Jestli chceš mermomocí udělat textovku pro ZX, použij PAW nebo Quill (viz. WoS), když nebudeš vymýšlet nějaké komplikované příkazy, tak to s "cestinou" půjde. Sám jsem to kdysi dávno zkoušel.

Ale jooo  ;) To byl jenom příklad, fungovat to bude bezpečně, to x$ jsem změnil, je to detail, jsem totiž zvyklý na Basic, kde se už $ nedává ani za stringové proměnné. Potřebuji si jen přijít na to, jak tenhle jednoduchý proces 3 kroků bude fungovat v assembleru, pak se dá již všechno zkomplikovat, přemostit, zavést tam další a další věci a podmínky...
Název: Re: Assembler z80
Přispěvatel: solaris104 5. Srpen 2010 - 20:34
Precti si celkem inspirujici clanek Jak psat textovky
http://zxwiki.80.cz/lib/exe/fetch.php?media=zxm:zxmagazin_1999-3.pdf
Název: Re: Assembler z80
Přispěvatel: zxretrosoft 5. Srpen 2010 - 22:13
Solaris104: Díky  ;) To je pěkný článek i časopis!  :)

Jinak už jsem skoro vyřešil bod č. 1, který jsem deklaroval. Říkám skoro, což je důležité, protože výstup je pořád nějak pokřivený a nemůžu to srovnat (viz příloha).

V knize je bohužel ten příklad tak nešikovně a nešťastně, že je skoro nemožné to kompletně dešifrovat.

Zjednodušil jsem to tedy na maximum, ale ještě se to musí doladit - možná bude někdo vědět jak na to  ::)

Kód: [Vybrat]
ent $
call #D6B
ld a,2
call #1601
ld hl,TEXT1
call TEXTOUT
TEXTOUT ld a,(hl)
and 127
rst 16
bit 7,(hl)
inc hl
jr z,TEXTOUT
ret
TEXT1 defb 22,15,10
defb 10,1
defm "ZX Spectrum"
ret

Některé věci jsou tam trochu komplikované, ale možná, že jsou nutné (např. and 127 v kombinaci s bit 7,(hl) inc hl a tou smyčkou). Zkoušel jsem je odstranit a ještě to zjednodušit, ale zdá se, že už to víc nejde...
S číslíčky u defb je možno si pohrát - ovlivňují pozici, barvu a jas textu.
Název: Re: Assembler z80
Přispěvatel: mop 6. Srpen 2010 - 00:13
Měl bych k tomu příkladu pár poznámek:

1. Ty dva znaky na konci tam máš proto, že po vykonání podprogramu TEXTOUT program normálně pokračuje tím, co následuje za instrukcí call TEXTOUT, a tedy vlastně znovu vykonává ten TEXTOUT. Řešení: instrukci ret, kterou máš teď úplně na konci, přesuň za call TEXTOUT, protože tady má správně ten program končit.

2. Chápu správně, že data defb 10,1 mají za cíl nastavit modrý inkoust? Pokud ano, tak tam má být buď defb 16,1 nebo hexadecimálně defb #10,1. Takhle to nedává smysl, a proto jsou tam ty otazníky na začátku.

3. Ty instrukce and a bit se obě zabývají nejvyšším bitem toho kterého bajtu, a podle tohoto bitu mají zřejmě za cíl poznat, kdy jsme dospěli na konec dat. Je to trochu zvláštní způsob, ale použít se dá. Musí se ale k poslednímu bajtu textových dat přičíst 128 (tedy dvojkově 10000000), čímž se jeho nejvyšší bit nastaví na 1. V tomhle případě tedy znak "m" nahradíme jeho hodnotou (109) zvýšenou o 128, což je 237.

Zkus to testnout:

Kód: [Vybrat]
ent $
call #D6B
ld a,2
call #1601
ld hl,TEXT1
call TEXTOUT
ret
TEXTOUT ld a,(hl)
and 127
rst 16
bit 7,(hl)
inc hl
jr z,TEXTOUT
ret
TEXT1 defb 22,15,10
defb 16,1
defm "ZX Spectru"
defb 237
Název: Re: Assembler z80
Přispěvatel: zxretrosoft 6. Srpen 2010 - 01:07
Díky!  ;) Už to začínám postupně chápat, s tím posledním znakem je to trochu neelegantní, ale budiž, dá se to akceptovat. Ještě se ale nemůžu dopracovat smyslu té první instrukce defb 22,15,10. Co přesně ta instrukce na tomhle místě dělá? Myslel jsem si, že určuje polohu textu, vypadá to ale, že je to komplikovanější...

Např. změním na defb 21,15,10 a zasekne se to. Změním na defb 1,15,10 a text je nahoře zleva, ale před ním jsou 3 otazníky. Zdá se, že tomuhle ještě nemůžu přijít na kloub  ::)

P.S. Nešlo by to i bez těch instrukcí and a bit ? případně bez toho zvláštního psaní posledního znaku?  ::)
Název: Re: Assembler z80
Přispěvatel: KaiN 6. Srpen 2010 - 08:20
mop: No já bych řekl, že ten příklad byl poněkud zmršen při úpravách. Původní ideou autora podle mě bylo, že ten příkaz ret, co je na konci toho textu, ve skutečnosti není příkaz, ale indikátor konce textu. Jeho kód je totiž "201", čili má nastaven nejvyšší bit na 1, což tisknutelné znaky nemají. A jinak souhlas, určitě tam nemůže být "10,1", ale "16,1" tj. INK 1.
Název: Re: Assembler z80
Přispěvatel: mop 6. Srpen 2010 - 10:40
Např. změním na defb 21,15,10 a zasekne se to. Změním na defb 1,15,10 a text je nahoře zleva, ale před ním jsou 3 otazníky. Zdá se, že tomuhle ještě nemůžu přijít na kloub  ::)
Nesmíš měnit ten bajt 22, ten právě určuje, že chceme použít fuknkci AT. Měň až ty dvě číla za ním, což jsou ty souřadnice.
Název: Re: Assembler z80
Přispěvatel: mop 6. Srpen 2010 - 11:04
P.S. Nešlo by to i bez těch instrukcí and a bit ? případně bez toho zvláštního psaní posledního znaku?  ::)

Určitě šlo, já bych na konec těch dat dal normálně bajt o hodnotě 13, což je taková tradiční hodnota pro end-of-line neboli koncový znak jakéhokoliv řetězce.

Kód: [Vybrat]
ent $
call #D6B
ld a,2
call #1601
ld hl,TEXT1
call TEXTOUT
ret
TEXTOUT ld a,(hl)
cp 13
ret z
rst 16
inc hl
jr TEXTOUT
TEXT1 defb 22,15,10
defb 16,1
defm "ZX Spectrum"
defb 13

Tedy hodnotu hned po uložení do A testujeme na koncový znak 13. Při rovnosti bez dalších cavyků ukončujeme podprogram. Jinak vypisujeme znak, zvyšujeme ukazatel HL a jdeme na začátek cyklu.
Název: Re: Assembler z80
Přispěvatel: KaiN 6. Srpen 2010 - 11:25
Tak to já bych tam spíš dal tradiční bajt o hodnotě 0.  ;) 13 se mu může přece hodit, když bude chtít přejít v rámci odstavce na nový řádek, aniž by se musel plácat s mezerama.
Název: Re: Assembler z80
Přispěvatel: mop 6. Srpen 2010 - 11:39
Máš pravdu, lepší bude nula, nebo prostě jakákoliv hodnota, která se nevyužívá k nějakému jinému účelu.
Název: Re: Assembler z80
Přispěvatel: zxretrosoft 6. Srpen 2010 - 12:59
Klucí, díky!  ;) S tou nulou to nefunguje, s defb 13 jo. Takhle to opravdu vypadá elegantněji, přece jen už mi to dává nějaký smysl. Teď ještě přijít na ten zbytek, tj. INPUT a podmínka za tím  :)
Jdu to ještě studovat  ::) p.s. vzhledem k tomu, že v knize Assembler a ZX Spectrum na téma vstup a vyhodnocení textu je stručný příkládek na pouhých 9 stránek  :P
Název: Re: Assembler z80
Přispěvatel: mop 6. Srpen 2010 - 14:21
To je divný, že ti to nešlo s tou nulou. Změnil jsi to na obou místech? (u instrukce CP a na konci u DEFB)
Název: Re: Assembler z80
Přispěvatel: zxretrosoft 6. Srpen 2010 - 14:29
To je divný, že ti to nešlo s tou nulou. Změnil jsi to na obou místech? (u instrukce CP a na konci u DEFB)

Ano, jasně s tou nulou to jde - nezměnil jsem to u té první instrukce. Když se to změní u obou, tak to jde v pohodě  ;)
Název: Re: Assembler z80
Přispěvatel: zxretrosoft 11. Srpen 2010 - 10:32
Zkoumal jsem teď nějaký čas různé prográmky v assembleru různých autorů, některé se mi podařilo rozbalit bez problémů, a zjistil jsem, že porozumět assembleru je skvělé, ale 90% autorů využívá hojně hotové podprogramy - prováděcí podprogramy, příkazové podprogramy, aritmetické podprogramy atd.

Kompletní výpis ZX ROM lze najít např. tady: http://softhouse.speccy.cz/documents/download/ZX_ROM.pdf (http://softhouse.speccy.cz/documents/download/ZX_ROM.pdf)

To mě bohužel zklamalo. Je to opravdu často zplácané z těchto rutinek, autoři si osvojí jen to, kde ušetřit čas (kroky), tam použijí zase jiný ("poctivější") způsob a pak se vrátí zase do podprogramů. Rychlost je pořád lepší než v Basicu. U většiny věcí se to tak nepozná, skutečný assembler se vším všudy je jen tam, kde už autoři zápasí s RAM či s každým krokem kvůli rychlosti...

Výpis ZX ROM je skutečně základní stavební kámen většiny programů v assembleru, takže asi taky něco zkusím, ať vypadám, že tomu rozumím  ;D
Název: Re: Assembler z80
Přispěvatel: lanex 20. Červen 2011 - 17:59
opráším další staré téma:

tvůj příklad volá standartní rutiny v ROM, které jsou určené pro použití v ZX Basicu, a jsou pro ně optimalizované. Pro volání ze strojového kodu jsou ale nevhodné, protože jim to zkrátka hrozně dlouho trvá. Pokud chceš z procesoru s kmitočtem 3,54 MHz vymačknout maximum, musíš se téměř kompletně vyhnout rutinám v ROM. Pokud se rutinám v ROM vyhnout nechceš nebo nemůžeš, neni důvod psát tvuj program v ASM, protože stejně dosáhneš podobné rychlosti jako kdybys ho psal v ZX Basicu.
Název: Re: Assembler z80
Přispěvatel: zxretrosoft 22. Červen 2011 - 22:46
opráším další staré téma:

tvůj příklad volá standartní rutiny v ROM, které jsou určené pro použití v ZX Basicu, a jsou pro ně optimalizované. Pro volání ze strojového kodu jsou ale nevhodné, protože jim to zkrátka hrozně dlouho trvá. Pokud chceš z procesoru s kmitočtem 3,54 MHz vymačknout maximum, musíš se téměř kompletně vyhnout rutinám v ROM. Pokud se rutinám v ROM vyhnout nechceš nebo nemůžeš, neni důvod psát tvuj program v ASM, protože stejně dosáhneš podobné rychlosti jako kdybys ho psal v ZX Basicu.

Ano, to je principiálně pravda, ovšem šlo o to, že mnoho prográmků, které jsem listoval a všemožně pročítal, mají podobný autorův "podpis". Jeho postup je totiž zpravidla tento:


Jen málokdy se dá mluvit o tom, že autor chápe celý program v ASM, nebo že vyráží ze Z80 maximum. Tímhle postupem skládání programu jako puzzle dosáhne většinou zajímavého výsledku, "prográmku ve strojáku", aniž by ASM naplno využíval či chápal...

To se ostatně ukazuje na mnoha fórech věnovaných ASM. Téměř všichni, co něco napsali v ASM, to nedokáží vysvětlit, jen opakují fráze typu: "No prostě dej tam ld b,a pak ld hl,0 a ret". Samozřejmě když se zeptám, proč třeba zrovna ld hl,0 , tak na to vůbec neodpoví nebo zopakují frázi, nebo ze mě udělají blbce  ::)

Je to také asi tím, že počet lidí, kteří by alespoň potenciálně mohli umět v ASM Z80, je minimum (a byl minimum už v 90. letech, natož teď), takže člověku nezbývá, než se ponořit do Bity do bytu od L. Zajíčka (či něco obdobného) a studovat to pořád dokola...  :)
Název: Re: Assembler z80
Přispěvatel: lanex 24. Červen 2011 - 22:02
Zřejmě jsi jen nenarazil na ty správný lidi :)

Připravil jsem ti malý příklad na srovnání "Vlastní rutina vs Rutina v ROM", aby se mluvilo o konkrétních hodnotách:
Napsal jsem si pro účely měření obdobný program, jako je zde uvedený první příklad v ASM (vykreslí čtverec znaků 8x8 v různých barvách za pomocí ROM), a šel jsem měřit :)

- Příklad zde uvedený na začátku, co tiskne s pomocí ROM rutiny RST 16 tento čtverec vytiskl na obazovku za 571804 taktů (159,74 ms)

- příklad který jsem si ted tady napsal v ASM, používá mnou napsaný "LnxPrint" :) , vytiskl na obrazovku tentýž čtverec za 60786 taktů (16,98 ms)

Výsledek:

Za pomocí ROM se za sekundu dá vytisknout 400,65 znaků (cca půl obrazovky za sekundu). Moje rutina zvládne za sekundu 3769,14 znaků (cca 5 obrazovek za sekundu).

ROM rutina je tedy skoro 10x pomalejší :) Ani jsem si nemyslel, že to bude až takový rozdíl :)

Přikládám i ASM:
Kód: [Vybrat]
org     50000 ;kompilovat budeme od adresy 50000

                ld c,8 ;budeme tisknout box o 8mi řádcích...
LOOP            ld b,8 ;a 8 sloupcích
LOOP2           push    bc ;uchováme si BC pro jeho obnovení - protože ho při tisknu zničíme

                dec     b ;tady pořešíme barvy. Barva na ZX je v rozsahu 0-7, ne 1-8,
                dec     c ;takže barvu popředí (ink) a pozadí (paper) snížíme o jednu
                ld      a,b ;attribbut barev na ZX je FBPPPIII (Flash-Bright-Paper-Ink)
                sla     a ;proto posuneme barvu PAPERu o 3 doleva, aby byl na správné pozici
                sla     a
                sla     a
                or      c ;a sloučíme s INK, tím dostaneme správný Attribut barvy pro videoram
                ld      (Barva),a ;uložíme do paměti pro tiskovou rutinu

                call    PrintAT ;Zavoláme "Print At regB,regC", tedy nastavíme pozici příštího znaku na obrazovce

                ld       a,64 ;budeme tisknout znak zavináče (ascii 64)
                call    LnxPrint ;a natiskneme znak

                pop     bc ;obnovíme zničené registry BC
                djnz    LOOP2 ;už je celá řádka vytištěná?
                dec      c
                jr       nz,LOOP ;už jsou všechny řádky vytištěné?
                ret ;návrat (kam? no přece tam, odkud jsme to volali :) třeba do bejziku)

; A tady je moje náhrada za RST16:

LnxPrint:       sub     32 ;v RegA máme znak co chceme tisknout. Ascii tabulka začíná od 32 znaku
;(0-31 jsou spec řídící znaky)
                ld      d,0 ;Musíme najít adresu, kde začíná ve fontu písmeno co hledáme.
                ld      e,a ;Z regA si uděláme 16tibitový reg DE, a počítáme:

                sla     e ;DE=DE*8 (v případě @ vypadne 512)
                rl      d
                sla     e
                rl      d
                sla     e
                rl      d

                ld      hl,15616 ;a příčteme adresu písma v ROM (Fontu) HL= HL+DE
                add     hl,de

                ld      de,(PrintAdr) ;do DE si vezmeme adresu do videoram, kterou nám vypočítal Print At regB,regC
                ld      b,8 ;každé písmenko má 8 linek
LnxPrint3:      ld      a,(hl) ;tak je tady všechny zkopírujeme na obrazovku
                ld      (de),a
                inc     d ;další linka na obrazovce je o 256 bajtů dále
                inc     l ;další linka je ve fontu o 1 bajt dále
                djnz    LnxPrint3

                ld      hl,(ColorAdr) ;do HL si vezmeme adresu do color-videoram, kterou nám vypočítal Print At regB,regC
                ld      a,(Barva) ;načteme si hodnotu barvy
                ld      (hl),a ;a cákneme to na to naše písmenko. Znak je na obrazovce, a i v barvě :)

                ld      hl,(PrintAdr) ;opět si načteme adresu do videoram, kterou nám vypočítal Print At regB,regC
                inc     l ;příští písmenko bude o jednu pozici vpravo
                ld      (PrintAdr),hl ;uložíme zpět do paměti
                ld      a,0 ;Zkontrolujem, zda nám pozice znaku nepřetekla do jiné třetiny obrazovky
                cp      l
                jr      nz,LnxPrint4
                ld      de,2048 ;přetekla, takže jdeme s příštím znakem do následujicí třetiny obrazovky
                add     hl,de ;k adrese tedy připočteme 2048
                ld      (PrintAdr),hl ;a uložíme do paměti

LnxPrint4:      ld      hl,(ColorAdr) ;i adresa color-videoram se o jednu pozici posune doprava
                ld      de,1 ;naštěstí nemusíme kontrolovat třetiny, jako tomu bylo u videoram
                add     hl,de
                ld      (ColorAdr),hl ;a uložíme do paměti
                ret ;Znak vytištěn, a nová pozice připravena. Naschledanou

PrintAT:        ld      hl, 16384 ;Budeme zjištovat adresu do videoram podle X (v regB) a Y (v reg C)
                ld      de, 2048 ;videoram je rozdělena na třetiny po 2048 bajtech a proto
                ld      a,b ;budeme testovat jestli Y nezasahuje do jiné třetiny (8mej řádek a více)
LnxPrint2:      cp      8 ;8 řádků a víc?
                jr      c,LnxPrint1 ;jestli ne, jsme ve správné třetině a jdeme dál=>LnxPrint1
                add     hl,de ;ano, 8 a víc, znak se tedy nenachází v této třetině videoram (skočíme do
                sub     a,8 ;následující třetiny tak, že přičteme 2048 k videoram a snížíme pozici Y o 8)
                jr      LnxPrint2 ;a znovu otestuj, jestli není dokonce ve 3tí třetině

LnxPrint1:      sla     a ;Od ted pracujeme jen v jedné třetině obrazovky, Y není větší jak 7
                sla     a ;(páč 8 a víc by byla úplně jiná třetina obrazovky)
                sla     a ;na každé řádce je 32 znaků, 33 znak je vlastně první znak na
                sla     a ;další řádce
                sla     a ;vynásobíme tedy Y * 32
                ld      d,0 ;přeneseme do DE
                ld      e,a
                add     hl,de ;a připočteme k adrese videoram uloženou v HL
                ld      e,c ;do DE nyní vložíme X
                add     hl,de ;a také přičteme k adrese videoram v HL
                ld      (PrintAdr),hl ;tu potom uložíme do paměti.

                ld      hl,22528 ;Nyní si vypočteme adresu color-videoram
                add     hl,de ;přičteme k ní pozici X (která nám od minule zůstala v DE
                ld      e,b ;potom do DE dáme Y
                sla     e ;a vynásobíme 32x (32 protože každý 33 znak je vlastně 1 znak na další řádce)
                sla     e
                sla     e ;(tady je malej fígl pro zrychlení = číslo co násobíme není větší jak 23
                sla     e ;takže se vejde do 5ti bitů. Poslední 3 bity tedy nemůžou přetéct
                rl      d ;a tak 3 bity počítám jen 8mibitově a tedy rychleji. Potom už ale musím přejít
                sla     e ;na 16tibitové nasobení, ale jen kvuli dvoum bitum :) úplný turbo :D )
                rl      d
                add     hl,de ;a přičteme k color-videoram v HL
                ld      (ColorAdr),hl ;uložíme
                ret ;a jdeme doprdele odsud :)

PrintAdr:       defw    0 ;tady nám Print At uloží adresu do videoram, kam cpát znak
ColorAdr:       defw    0 ;tady totež, jen color.videoram
Barva:          defb    15 ;touhle barvou budeme tisknout znak
Název: Re: Assembler z80
Přispěvatel: KaiN 27. Červen 2011 - 11:21
Není nad komentovaný výpis programu...  ;)
Název: Re: Assembler z80
Přispěvatel: zxretrosoft 27. Červen 2011 - 13:41
Není nad komentovaný výpis programu...  ;)

Ano, ano, to je přesně ono, co říkám  :)

Každopádně díky lanexovi za ukázku, je vidět, že umí  ::) Nicméně pro mne to znamená prakticky to samé - studovat každý příkaz zvlášť a pokoušet se pochopit, co který dělá a proč je umístěn tam, kde je umístěn.

Řeknu to ještě jednou. Je to jako kdyby někdo přiletěl z Marsu a pokoušel se pochopit BASIC pouze z ukázkového programu. Studoval by to zhruba následujícím způsobem:


Atd.
Takže co tím chci ukázat je jen to, že člověk by se to měl učit zhruba opačně, tj. zafixovat si určité souvislosti, aby pochopil například komentář typu: "teď rotujeme akumulátor a to celkem 10x" apod. Je potřeba vědět, proč se to má udělat, možná je dobré vědět, co je to akumulátor a proč na něho v té chvíli mám sáhnout? Jinak je veškeré studium plané, a námaha odpovídá zhruba tomu Marťanovi  :)
Název: Re: Assembler z80
Přispěvatel: lanex 27. Červen 2011 - 15:50
no on ten kód byl původně myšlený spíš pro měření, než pro výuku. Ale pokud se to hodí i pro výuku, tak vám to okomentuju: kód je nyní okomentován. Je fakt, že to okomentování mi dalo víc práce, než samotný kód...  ;D
Název: Re: Assembler z80
Přispěvatel: KaiN 28. Červen 2011 - 12:01
U mě dobrý.  ;) Počítání taktů a optimalizace strojáku, to u mě nehrozilo, já byl rád, když to vůbec dělalo to, co mělo, a nedělalo to, co nemělo. :) Když jsem např. udělal rutinku, která vypisovala 42 znaků na řádek, a nastavil jí jako kanál u příkazu "LPRINT", protože naprostá většina programu byla dělána v BASICu, tak jsem se bil v prsa, jaký jsem těžký frajer.  :)
Název: Re: Assembler z80
Přispěvatel: zxretrosoft 30. Červen 2011 - 22:18
Poraďte mi, prosím, nějaký editor, do kterého se dá assembler snadno psát. Mně to v tom Prometheovi opravdu moc nesedí, i když je to celkově bez problémů, trvá to poměrně dlouho než něco napíšu či přepíšu. Radši bych přirozeně používal něco moderního, když už je ta možnost  :) Např. geniální editor na BASIC ZX jménem BasIN mě doslova uchvátil  8)

Zkoušel jsem ten assembler naposled opět v EmuZWin (assembler++), který mi přijde nejsympatičtější, ale pořád nemůžu ten prográmek ve výsledku spustit. Nevíte náhodou jak na to?

Ve Spectacularovi jsem nic podobného nenašel, asi to bohužel neumožňuje...  :-\
Název: Re: Assembler z80
Přispěvatel: lanex 1. Červenec 2011 - 09:48
WinZemu vypadá slušně, bohužel díky katastrofálním bugům se hodí jen na drobné pokusy, jako třeba LnxPrint :) Prometheus je přecijen stále hvězdou :)

Jak spustit zkompilovaný program ve WinZemu: nahoře je ikonka "Assembly", je to ta vlevo vedle "L:". Tím vytvoří do paměti určenou příkazem ORG strojový kod. Spustí se normálně emulace, a z BASICu se kod spustí. Randomize User 50000 (adresa v ORG). Pozor, pokud se Spectrum restartuje, strojový kod vždycky smaže. Po restartu se musí znovu zAssemblovat, než se zavolá příkazem Randomize Usr 50000.
Název: Re: Assembler z80
Přispěvatel: mop 1. Červenec 2011 - 21:03
Citace
Radši bych přirozeně používal něco moderního, když už je ta možnost

V diskusi u Pavera na webu se před pár dny objevil odkaz na zDevStudio, což je letošní projekt zatím ve verzi 0.7. Zkoušel jsem zatím jen lehce, ale vypadá to použitelně. Zvýraznění syntaxe vypadá v podstatě stejně jako obrázek, který jsi přiložil (+ všechny barvičky jsou nastavitelné). Umožňuje to nastavit libovolnou příponu výsledného souboru a má to i nějaká přednastavení pro .tap a .tzx, takže jestli píšeš pro Spectrum, možná by to stálo za zkoušku.

http://zdevstudio.sourceforge.net/
Název: Re: Assembler z80
Přispěvatel: mop 2. Srpen 2011 - 00:57
Díky dalšímu přídělu pošmourného počasí jsem zase trochu tvořil ve zmiňovaném zDevStudiu a musím říct, že se mi v tom dělá pohodově. Začal jsem tvořit něco, z čeho by snad časem mohla být nová textovka pro Sharp MZ-800. Samozřejmě je to hudba budoucnosti, protože nadatlovat něco takového čistě v assembleru je na dlouhé lokte, ale i tak bych se chtěl už teď zeptat, kdo na tomhle fóru má vůbec emulátor Sharpa a byl by schopen a ochoten si zahrát, případně i formou testování nějakých pracovních verzí.
Název: Re: Assembler z80
Přispěvatel: KaiN 2. Srpen 2011 - 22:43
Mám emulátor, o kterém se tu někde psalo. Rád otestuji. Panprase může poskytnout dobrozdání, jaký jsem vynikající tester.  :D
Název: Re: Assembler z80
Přispěvatel: panprase 29. Srpen 2011 - 23:47
No KaiN je fakt vynikající tester.