<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="pl">
	<id>https://mirror.atariki.pl/w/index.php?action=history&amp;feed=atom&amp;title=Programowanie%3A_Techniki_przyspieszania_kodu</id>
	<title>Programowanie: Techniki przyspieszania kodu - Historia wersji</title>
	<link rel="self" type="application/atom+xml" href="https://mirror.atariki.pl/w/index.php?action=history&amp;feed=atom&amp;title=Programowanie%3A_Techniki_przyspieszania_kodu"/>
	<link rel="alternate" type="text/html" href="https://mirror.atariki.pl/w/index.php?title=Programowanie:_Techniki_przyspieszania_kodu&amp;action=history"/>
	<updated>2026-10-03T21:18:46Z</updated>
	<subtitle>Historia wersji tej strony wiki</subtitle>
	<generator>MediaWiki 1.46.0</generator>
	<entry>
		<id>https://mirror.atariki.pl/w/index.php?title=Programowanie:_Techniki_przyspieszania_kodu&amp;diff=3308&amp;oldid=prev</id>
		<title>imported&gt;Atariki recovery: Reconstructed from archived HTML; see provenance manifest</title>
		<link rel="alternate" type="text/html" href="https://mirror.atariki.pl/w/index.php?title=Programowanie:_Techniki_przyspieszania_kodu&amp;diff=3308&amp;oldid=prev"/>
		<updated>2026-10-01T08:51:48Z</updated>

		<summary type="html">&lt;p&gt;Reconstructed from archived HTML; see provenance manifest&lt;/p&gt;
&lt;p&gt;&lt;b&gt;Nowa strona&lt;/b&gt;&lt;/p&gt;&lt;div&gt;Ta strona zawiera proste metody, które mogą często znacząco przyspieszyć działanie programu.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Szybsze zapamiętywanie rejestrów w przerwaniach ===&lt;br /&gt;
&lt;br /&gt;
Kiedy obsługujemy przerwania (np. [[DLI]]), powinniśmy zapisać wartości rejestrów, i odtworzyć je przy wyjściu (oczywiście, tylko rejestry, które będziemy modyfikowali).&lt;br /&gt;
Typowo, jest to robione poprzez:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
enter&lt;br /&gt;
  pha  ; 3 cykle&lt;br /&gt;
  txa  ; 2&lt;br /&gt;
  pha  ; 3&lt;br /&gt;
  tya  ; 2&lt;br /&gt;
  pha  ; 3&lt;br /&gt;
  ...&lt;br /&gt;
leave&lt;br /&gt;
  pla  ; 4&lt;br /&gt;
  tay  ; 2&lt;br /&gt;
  pla  ; 4&lt;br /&gt;
  tax  ; 2&lt;br /&gt;
  pla  ; 4&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
To rozwiązanie, chociaż proste, zajmuje w sumie w sumie 29 cykli. W przypadkach, kiedy mamy dużo przerwań, np. DLI co 2 linie, jest szybsza metoda:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
enter&lt;br /&gt;
  sta _value_a+1  ; 4 cykle&lt;br /&gt;
  stx _value_x+1  ; 4&lt;br /&gt;
  sty _value_y+1  ; 4&lt;br /&gt;
  ...&lt;br /&gt;
leave&lt;br /&gt;
_value_a lda #0   ; 2&lt;br /&gt;
_value_x ldx #0   ; 2&lt;br /&gt;
_value_y ldy #0   ; 2&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
To zajmuje 18 cykli, zatem pozwala oszczędzić 11 cykli na obsługę przerwania. Zajmuje 5 bajtów więcej, ale zazwyczaj ten koszt jest pomijalny.&lt;br /&gt;
&lt;br /&gt;
Powyższą procedurę możemy umieścić w całości na stronie zerowej, przez co instrukcje sta,stx,sty value wykonają się o jeden cykl mniej, w ten sposób oszczędzamy 3 cykle na przerwanie. Jeżeli mamy np. przerwanie DLI co 1 linię ekranową występujące przez 200 linii rachunek wydaje sie prosty, oszczędzany 600 cykli. Zyskujemy trochę cykli kosztem zajęcia części strony zerowej poprzez kod procedury obsługi przerwania. Jednak czasami jest to opłacalne.&lt;br /&gt;
&lt;br /&gt;
Strony zerowej można też użyć do przechowywania rejestrów, zmniejszy to dodatkowy koszt pamięci z 5 bajtów do 2, przy tym samym czasie wykonania:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
zp_a $80&lt;br /&gt;
zp_x $81&lt;br /&gt;
zp_y $82&lt;br /&gt;
 ...&lt;br /&gt;
enter&lt;br /&gt;
 sta zp_a&lt;br /&gt;
 stx zp_x&lt;br /&gt;
 sty zp_y&lt;br /&gt;
 ...&lt;br /&gt;
leave&lt;br /&gt;
 lda zp_a&lt;br /&gt;
 ldx zp_x&lt;br /&gt;
 ldy zp_y&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
To rozwiązanie jest dodatkowo przydatne w sytuacjach, gdy w procedurze przerwania mamy więcej niż jedno miejsce wyjścia, np w związku ze skokiem warunkowym.&lt;br /&gt;
&lt;br /&gt;
=== Skoki do adresów w tablicy ===&lt;br /&gt;
&lt;br /&gt;
Są sytuacje, gdzie chcemy skoczyć pod różny adres w zależności np od wartości rejestru Y.&lt;br /&gt;
Przykładowym rozwiązaniem jest trzymanie tablicy adresów, podzielonych na lo/hi adres, i użycie automodyfikacji kodu (ten sam kod dla JSR i JMP):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  lda skoki_lo,y  ; 4 cykle&lt;br /&gt;
  sta _skok+1     ; 4&lt;br /&gt;
  lda skoki_hi,y  ; 4&lt;br /&gt;
  sta _skok+2     ; 4&lt;br /&gt;
_skok jsr adres   ; 6, lub JMP, 3 cykle&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Innym sposobem na wykonanie skoku jest wykorzystanie właściwości rozkazu RTS. Nadal potrzebujemy tablic adresów, podzielonych na lo/hi adres-1 (koniecznie adres pomniejszony o 1). Takie rozwiązanie użyteczne jest w przypadku programów na karcie gdzie nie mamy możliwości automodyfikacji kodu.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 lda skoki_hi,y   ; 4 cykle&lt;br /&gt;
 pha              ; 3&lt;br /&gt;
 lda skoki_lo,y   ; 4&lt;br /&gt;
 pha              ; 3&lt;br /&gt;
 rts              ; 6 = 20 cykli&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Dla JSR, w sytuacji, gdy liczba skoków jest ograniczona do 86, możemy stworzyć specjalną dodatkową tablicę, zawierającą nie adresy skoków, ale rozkazy JMP, tzn:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
skoki&lt;br /&gt;
  jmp skok1  ; 3 cykle&lt;br /&gt;
  jmp skok2&lt;br /&gt;
  ...&lt;br /&gt;
  jmp skokN  ; max N to 86&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Jeśli ten kod umieścimy tak, że &amp;lt;code&amp;gt;skoki&amp;lt;/code&amp;gt; rozpoczynają się na początku strony, możemy użyć następującej konstrukcji:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  lda mul3,y      ; 4 cykle&lt;br /&gt;
  sta _skok+1     ; 4&lt;br /&gt;
_skok jsr skoki   ; 6&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
W ten sposób zaoszczędzamy 5 cykli, bo unikamy lda/sta (-8 cykli) ale dodajemy pośredni jmp (+3), kosztem dodatkowej pamięci.&lt;br /&gt;
&lt;br /&gt;
Dla JMP, możemy to zrobić jeszcze inaczej, używając rozkazu JMP (adres). Nasza tablica &amp;lt;code&amp;gt;skoki&amp;lt;/code&amp;gt; powinna zawierać po kolei adresy docelowe, czyli:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
skoki&lt;br /&gt;
  dta a(skok1)&lt;br /&gt;
  dta a(skok2)&lt;br /&gt;
  ...&lt;br /&gt;
  dta a(skokN)     ; max N to 128&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
I teraz nasz kod zamieniamy na&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  tya             ; 2 cykle&lt;br /&gt;
  asl @           ; 2, mnożymy przez 2&lt;br /&gt;
  sta _skok+1     ; 4&lt;br /&gt;
_skok jmp (skoki) ; 5&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Oszczędzamy 6 cykli, bo usuwamy lda/sta (-8 cykli), ale zwiększamy koszt JMP z 3 do 5 (+2).&lt;br /&gt;
&lt;br /&gt;
=== Odejmowanie od (2 do X)-1 ===&lt;br /&gt;
&lt;br /&gt;
Są sytuacje, gdy chcemy odjąć liczbę (M) od (potęgi 2)-1, np 1, 3, 7, 15, ..., 255 (N). Typowy kod:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  lda N&lt;br /&gt;
  sec&lt;br /&gt;
  sbc M&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Jeśli wiemy, że M jest mniejsza-równa N, możemy to zrobić szybciej:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  lda M&lt;br /&gt;
  eor N&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Jest to szczególnie przydatne, gdy M mamy pod ręką, np już w A, wtedy całe odejmowanie ogranicza się do &amp;lt;code&amp;gt;eor&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
[[Kategoria:Niezbędnik kodera]]&lt;br /&gt;
&lt;/div&gt;</summary>
		<author><name>imported&gt;Atariki recovery</name></author>
	</entry>
</feed>