C64Power Forum
		Software => Programowanie => Wątek zaczęty przez: Navigator_ w 26 Marca 2003, 13:46
		
			
			- 
				Hejka! 
 
Ostatnio zaczalem sie ":bawic": assemblerem na C64. Zaciekawil mnie ten jezyk - a w zwiazku z tym, ze o assembler teraz nie trudno - sciagnalem sobie Turbo Assemblera V6, odkurzylem stare numery Commodore &: Amiga i przystapilem do dzialania. Wszystko bylo dla mie jasne i klarowne do 2 odcinka owego kursu. Zainteresowala mnie sprawa petli, wiec postanowilem zrobic cos sam (w zasadzie to na swoich danych - ale to taki skrot myslowy
. Wiec wstukalem taki oto programik 
 
         *=2710 
         ldx #$09 
loop  lda tekst,x 
         sta $0400,x 
         dex 
         bne loop 
         rts 
tekst .text":commodore": 
 
Ot niby prosta sprawa, wyswietlanie napisu na ekranie. Owszem wszystko byloby ok gdyby nie dziwne efekty. Przy skompilowaniu i uruchomieniu takiego programu uzyskuje nastepujace rezultaty: 
- napis jest wyswietlany od poczatku pierwszego wiersza (czyli od $0400) ale pierwsza litera (a konkretnie ":c"
 jest ":niewidzialna":, czyli uzyskujemy spacje (puste miejsce w pierwszym wierszu i pierwszej kolumnie) i ommodore. 
Sprawa jest o tyle dziwna ze gdy postawie spacje w wyrazie - czyli zamiast ":commodore": napisze ": commodore": i zaczne literki wypisywac od adresy o jeden mniejszego (czyli od $03ff) to wszystko dziala zgodnie z oczekiwaniami. 
 
Teraz pytanie do osob znajacych assembler: dlaczego ta sie dzieje. Czy moj program jest do dupy, czy adres powinien jednak byc $03ff, czy tak poprostu ma byc?? 
 
Sprawa mnie bardzo intryguje wiec prosilbym o odpowiedz. Dzieje sie tak i na VICE i na real C64. A moze to sprawa dla archiwum X?? 
 
Pozdrawiam
			 
			
			- 
				Przedewszystkim zamiast ldx #$09 wpisz ldx #$08 
Pozniej miedzy dex a bne loop woisz cmp #$ff 
i wszytko gra... 
 
Mnemonik bne znaczy - skocz jesli wynik operacji rozny od 0 
dlatego ":C": nie jest wyswietlane...  
 
Poprostu - jezeli w x masz #$01 i wykonasz dex (zmniejsz x) to otrzymasz 0  
wtedy rozkaz bne nie skoczy do loop tylko wykona sie nastepny rozkaz czyli rts. 
 
cmp - CoMPare (porownaj)
			 
			
			- 
				Dzieki za reakcje
 
No widzisz ja zawsze mowie ze teoria i prakatyka to dwie rozne sprawy:D Dlaczego?? Otoz niby wszystko dziala (zaznaczam ze narazie sprawdzilem na VICE bo w pracy nie mam jeszcze C64 - ale to kwestia zanlezienia u kogos znajomego zbywajacego C64
. Efekty sa nastepujace: 
- wyswietla sie owy napis - niech bedzie ten przykladowy commodore z c w inversie i mniej wiecej od adresu $04dc mam takie cos znaczek (cos jak by kwadrat podzielony na 4 z dziema cwiartkami zamalowanymi) i 36 znaczkow @. Osobiscie nie wiem po co porownuje zawartosc akumulatora z #$ff (chyba dobrze wydedukowalem?). A teraz najsmieszniejszy ":myk": ten listing jest w zasazdie zywcem 
 wziety z kursu w C &: A tylko tam zamiast  ldx #$09 bylo ldx #$2c a tekst to bylo cos w stylu prawdziwy maniak petli sie nie boi (czy jakos tak). Skoro taki listing pokazal sie w gazecie ":branzowej": to nie sadze zeby napisal to ktos kto o assie nie ma pojecia (aczkolwiek glowy za to nie dam). Nie jestem pewien ale chyba kiedys to sprawdzalem na C128 chyba (w trybie C64 oczywiscie) i dzialalo bez zajakniecia. Wiec czemu podany kod nie dziala jak nalezy?? NIby proste wyswietlanie ":literkoof": a tyle z tym zachodu. Moze to kwestia samego kompilatora (uzywam czego oznaczonego jako Turbo Assembler v6). Poza tym ciekawi mnie konstrukcja sta $0400,x a potem dex - czyzby napis byl wyswietlany od konca?? 
 
A co do mnemonikow to znam i ch znaczenie - ot taka ciekawosc zza czasow kiedy nie moglem uzywac assemblera ze wzgledu na brak stacji dyskow, ale czytalm wszystko na ten temat bo mnie to poprostu bardzo interesowalo 
 Ale mimo wszystko dziekuje za przypomnienie. 
 
Pozdrawiam.
			 
			
			- 
				Oczywiscie ze zamiast cmp winno byc cpx (stad te smiecie...)
			
 
			
			- 
				Zeczywiscie tekst ten jest wyswietlany od konca  
Normalnie wygladalo by to tak: 
 
          *=$2710 
          ldx #$00 
loop   lda text,x 
          sta $0400,x 
          inx 
          cpx #$09 
          bne loop 
          rts 
text    .text ":COMMODORE":
			 
			
			- 
				oo wlasnie, ta metoda dziala bez zarzutu (napewno na VICEku), a ten invers tyczyl sie tej wczesniejszej metody. cos chyba zamotalem z wysylaniem posta 
 mimo wszystko dzieki, wyjasniles mi przy okazji (byc moze naewt i nieswiadomie
  inna kwestie. Dzieki!!
			 
			
			- 
				Sorki, ze tak katuje, ale zastanawia mnie taki problem: skoro mozna ten problem rozwiazac na dwa (w sensie wyswietlania od poczatku i od konca) sposby, to pojdzmy o krok dalej i gdybym chcial wyswietlic ten tekst od konca?? Wiemy ze tekst jest przechowywany (a w zasadzie to wychodzi ze tylko jego adres jest tam przechowywany) w akumulatorze i jego wartosc (??) jest powiekszona o zawartosc rejestru x.Wiec dziala to tak bierzemy pierwsza litere i wstawiamy do $0400, potem druga i do $0401 ja, potem kolejna i tak dalej i tak dalej. Ale zalozmy ze chcemy tak.  Bierzemy pierwszy znak i do ostatniej komorki go potem drugi i do wrzucamy go do przedostatniej. Ciekawi mnie to jak to zalatwic. Znajomy, ktory z assemblerem C64 nie ma nic wspolnego, ale programuje rozne takie smieszne procesory na PW, doradzil mi zeby uzyc drugiego rejestru (czyli w tym wypadku bylby to rejestr Y) i zmontowac takia petle w petli - jedna odpowiadalaby za pobieranie kolejnych znakow z zadanego ciagu, a druga za wyswietlanie tego na ekranie. Niby wszystko fajnie, ale nie udalo mi sie tego pozbierac w calosc. Z gory oczywiscie zakladajac ze znamy tylko: LDA xxxx, LDA xxxx,x, STA (i wariacje), BNE, CMP (plus mutacje), INX, DEX ( a po uzyciu rejestru Y doszloby pewnie jeszcze INY badz DEY). Problem dla mnie nie lada (znaczy sie dla osoby, ktora dopiero zaczyna). Wiem ze takie pytania sa denerwujace dla kogos tko opanowal assembler C64. Jednak zawsze bylem zwolennikiem jezykow niskiego poziomu, a teraz postanowilem opanowac przynajmniej podstawy jednego z nich. Padlo na C64 wlasnie ze wzgledu na prosty procesor (akumulator, dwa rejestry, kilka flag) i na wielki sentyment ktorym darze ten komputerek (wszakze to moj pierwszy). Mam nadzieje, ze nie dobijam poziomem skomplikowania problemow (chodzi mi czy nie sa zbyt lamerskie 
. 
 
Pozdrawiam
			 
			
			- 
				":Problemy": nie sa trudne , a ty masz prawo pytac , wiec Ci odpowiadam:  
 
   *=$1000 
ldx #$08 
ldy #$00 
loop  lda text,y 
sta $0400,x 
dex 
iny 
cpx #$ff 
bne loop 
rts 
text .text ":commodore": 
 
Chyba o to Ci chodilo?
			 
			
			- 
				a jednak nadal pierwszy znak jest w inwersie...czemu??
			
 
			
			- 
				Jesli chodzi o te ":C": w inwersie to wyjasnienie jest takie: 
 
TAS w czasie asemblacj zmienia dane w linii .text na kody ascii a nie na kody ekranowe 
Tak wiec litera ":C": (duza) ma kod ascii 195  
ale 195 jako kod ekranowy daje C w inwersie 
 
mozesz to sprawdzic wpisujac w pierwszy znak pierwszej lini lit. ":C": duza  
i wykonujac ?peek(1024) powinno wyskoczyc 67 
jesli wpiszesz poke 1024,195 wyskoczy C w iwersie 
 
Zeby sprawdzic jaki jest kod ascii danego znaku wpisz 
?asc(":LITERA": ) 
np: ?asc(":C": )  return 
 
 
A tak  na marginesie to co Ci uswiadomilem ? 
			 
			
			- 
				ano jak sobie zrobic konstrukcje warunkowa z pomoca rozkazu porownania, czyli podstawiam sobie cos gdzies i porownuje z jakas tam wartoscia, czyli moge zrobic petle rosnaca do jakiejs wartosci, a nie tylko malejaca do zera. A tak przy okazji to zerkni ze dwa posty w gore bo znowu cos pokrecilem z tym wysylaniem postow. 
A tak na marginesie wlasnie doszedlem o co chodzi z tym inwersem. 
 
dzieki.
			 
			
			- 
				Mozna to zrobic w ten sposob: 
 
zmienna=$1100 
 *=$1000 
 
 
ldx #$01           : zmienna=1 
stx zmienna 
 
lda #$01           :  ) 
cmp zmienna    :  >:    If zmienna = 1 then jump 
beq jump          :  ) 
lda #$02         : >: 
sta $0400       : >:  else 
rts 
 
jump sta $0400   :tutaj skok 
rts 
 
Jak towpiszesz i uruchomisz w lewym gornym rogu powinno pojawic sie ":a": 
teraz zmien ldx #$01 na ldx $00 lub inna wartosc rozna od 1 
 
Powinno pojawic sie ":b": 
 
 
rts
			 
			
			- 
				>:zmienna=$1100  
>: *=$1000  
 
 o kurde, ciekawy zapis jak dla mnie Lamera 
 Kazdego dnia sie ucze hehehe
			 
			
			- 
				Jest to jak najbardzie poprawny zapis, jeszcze nigdy mi sie nie zdazylo aby cos bylo nie tak. 
Moze inni robia to tak: 
*=$1000 
abc= $1100 
ale to ich sprawa , ja tam wole po swojemu 
			 
			
			- 
				dzieki za wyjasnienie sprawy drukowania napisu od konca, po porownaniu twojego listingu z moim prototypem okazalo sie ze bylem bardzo blisko. powiem wiecej jeden rozkaz zawazyl (u mnie zamiast beq bylo bne - nie zglebiulem roznicy miedzy nimi
. analizujac listing tego programiku z warunkiem wykombinowalem sobie tak: a gdyby zamiast zmiany znaku zmienic miejsce jego wystepowania? oto efekt: 
 
x=$1100 
*=$1000 
ldx #$01 
stx x 
lda #$01 
cmp x 
beq jump 
sta $0400 
rts 
jump sta $07e7 
rts 
 
Jesli warunek jest spelniony to znak (ktorego kod jest ladowany do akumulatora w lda #$01) jest wyswietlany w ostatniej pozyzji ekranu, a jezeli ldx i lda operuja roznymi wartosciami w tedy nasz znak laduje w pierwszej komorce pamieci ekranowej. Dobrze rozumuje?? Mamy tu doczynienia z warunkami kiedy oczekujemy ze jakas rownosc zostanie spelniona (beq czyli Branch if EQual to zero - zapala sie flaga Z i rozkaz skacze pod wskazany adres), a gdyby zalezalo nam na sytuacji odwrotnej, czyli wykonac czekamy az warunek nie zostanie spelniony to wtedy nalezaloby uzyc BNE (Branch if Not Equal to zero), czy tak?? 
 
A aprops sprawy z umieszczaniem ":deklaracji zmiennych":, to skoro Turbo Assembler nie widzi roznicy miedzy 
 
*=$xxxx 
abc=$yyyy 
 
a 
 
abc=$yyyy 
*=$xxxx 
 
to nie ma znaczenia w jakiej kolejnosci te linie beda nastepowaly. efekt jest ten sam - program dziala, wiec kazdy bedzie stosowal ta wersje ktora mu najbardziej pasuje. wg. mnie ta druga jest nawet wygodniejsze bo zmiennych szukam sobie na poczatku (jezeli musze je znalezc). A tak przy okazji to dzieki za lopatologiczne (skoro zrozumialem - znaczy sie chyba zrozumialem
 wyjasnienie problemow i za cierpliwosc w odpisywaniu. zapewne jeszcze nie raz bede mial problem wiec pytam - czy na przyszlosc moge sie zwracac w podobnych kwestjach z prosba o wyjasnienie?? moze juz nie na lamach forum, ale via e-mail czy co tam jeszcze... 
jeszcze raz dzieki i pozdrawiam
			 
			
			- 
				No problemo 
 
Wal smialo.