26

(130 odpowiedzi, napisanych Scena - 8bit)

Błąd konwersji leżał po stronie programu "DETOKEN.BAS" który mniej ważną część adresu podanego bezpośrednio w stokenizowanym pliku zniekształca.

Będę wchodził w mało interesujące szczegóły (ostrzeżenie przed dalszym czytaniem).

Stąd wynikała konieczność poprawiania deklaracji zmiennych systemowych (SETVBL, EXTVBL, POKEY). Poza jeszcze jednym skokiem do procedury systemowej (której nieprawidłowy adres też zauważyłem), tylko w jeszcze jednym miejscu konwersja wykonała się na adresie podanym bezpośrednio i tam też pojawił się nie wykryty wcześniej błąd, który zaskutkował ogólnie niepowodzeniem konwersji (brakiem powrotu do początku utworu).

Konkretnie chodzi o wiersz 250 pliku GOLDHUNT.M65

250  .WORD $FF0F

powinno być $FFFF

Poniżej zamieszczam linię kodu konwertera która zawiera moim zdaniem błąd oraz dwie dodatkowe linie kodu bezpośredniego kontekstu.

1400 IF A=5 THEN GET #1,[b]B[/b]:GET #1,A:L=L-2:GOSUB 1680:A=[b]B[/b]:GOSUB 1680:GOTO 1340

1680 C=INT(A/16):B=A-C*16
1690 PUT #2,HEX(C):PUT #2,HEX(B)
1700 RETURN 

27

(130 odpowiedzi, napisanych Scena - 8bit)

@Eagle: Rzeczywiście. Przyczyna jest taka że do kompilacji poddałem źródło (po konwersji) GOLDHUNT.M65 bez ostatniej linijki (4460).
EDIT: Przyczyna jest jednak poważniejsza, chociaż nadal nie wiem jaka (poza tym że to wina konwersji).

28

(130 odpowiedzi, napisanych Scena - 8bit)

Wygenerowana binarka w załączniku.
EDIT: skasowałem bo Eagle dołączył poprawioną wersję.


Ostatecznie udało się za pomocą programu "DETOKEN.BAS" dokonać konwersji, ale tylko "po kawałku", tzn. dzieląc plik na części od linii na której zakończyła się poprzednia próba (nie wiem dlaczego program nie zadziałał "normalnie").

Dla porządku dodam że potrzebne były jeszcze drobne poprawki w kodzie playera:

60 SETVBL = $E404
70 EXTVBL = $E404
80 POKEY = $D202

580  JSR $F202
60 SETVBL = $E45C
70 EXTVBL = $E462
80 POKEY = $D200

i zmiana nagłówka wygenerowanego pliku przez ATasm'a (dostosowałem też linię zawierającą "INCLUDE" w źródle "GOLDHUNT.M65)

29

(130 odpowiedzi, napisanych Scena - 8bit)

To jednak konwersja się nie udała a pliki są w całości (wielkość stok. pliku zapisana jest w 2. i 3. bajcie).

Poniżej listing konwertera (może się przydać również do analizy pliku stokenizowanego).

1000 REM MAC/65 TOKEN CONVERTER
1010 REM (C) 1987 ANALOG COMPUTING
1020 REM WRITTEN BY CHARLES BACHAND
1030 REM 
1040 DIM TS(255),TE(255),HEX(15)
1050 DIM A$(40),TOKEN$(500)
1060 GOSUB 1470:GOSUB 1660
1070 TRAP 1070:? :? "RETURN for directory or name of":? " MAC/65  file";
1080 INPUT A$:IF A$="" THEN GOSUB 1740:GOTO 1070
1090 OPEN #1,4,0,A$
1100 GET #1,A:GET #1,B
1110 IF A=254 AND A=B THEN 1130
1120 ? "$)Not a MAC/65 File!":GOTO 1070
1130 GET #1,A:GET #1,B
1140 ? :? "File length = ";A+B*256+4
1150 TRAP 1150:? :? "RETURN for directory or name of":? " OUTPUT  file";
1160 INPUT A$:IF A$="" THEN GOSUB 1740:GOTO 1150
1170 OPEN #2,8,0,A$
1180 REM 
1190 REM PROCESS A LINE
1200 REM 
1210 TRAP 1440
1220 GET #1,A:GET #1,B:GET #1,L
1230 L=L-3:PRINT #2;A+B*256;" ";
1240 GET #1,A:L=L-1:IF A<>88 THEN 1270
1250 FOR B=1 TO L:GET #1,A:PUT #2,A
1260 NEXT B:PRINT #2:GOTO 1220
1270 IF A<128 THEN 1320
1280 FOR I=129 TO A:GET #1,A
1290 PUT #2,A:L=L-1:NEXT I
1300 IF L=0 THEN ? #2:GOTO 1220
1310 GET #1,A:L=L-1
1320 ? #2;" ";TOKEN$(TS(A),TE(A));" ";
1330 IF A=0 THEN 1250
1340 IF L=0 THEN ? #2:GOTO 1220
1350 GET #1,A:L=L-1
1360 IF A>128 THEN C=A:FOR B=129 TO C:GET #1,A:PUT #2,A:L=L-1:NEXT B:GOTO 1340
1370 IF A=7 THEN GET #1,A:GET #1,B:? #2;A+B*256;:L=L-2:GOTO 1340
1380 IF A=8 THEN GET #1,A:? #2;A;:L=L-1:GOTO 1340
1390 ? #2;TOKEN$(TS(A+128),TE(A+128));:IF A=6 THEN GET #1,A:GOSUB 1680:L=L-1:GOTO 1340
1400 IF A=5 THEN GET #1,B:GET #1,A:L=L-2:GOSUB 1680:A=B:GOSUB 1680:GOTO 1340
1410 IF A=59 THEN FOR B=1 TO L:GET #1,A:PUT #2,A:NEXT B:? #2:GOTO 1220
1420 IF A=10 THEN GET #1,A:PUT #2,A:L=L-1
1430 GOTO 1340
1440 A=PEEK(195):IF A=136 THEN 1070
1450 ? "$)ERROR #";A;" AT LINE ";PEEK(186)+PEEK(187)*256:STOP 
1460 REM 
1470 REM SET-UP TOKEN TABLES
1480 REM 
1490 ? :? " MAC/65  TOKEN CONVERTER"
1500 ? :? "Initializing arrays, ";
1510 ? "please wait...":C=1
1520 READ TOKEN,A$:IF TOKEN<>-1 THEN GOSUB 1600:GOTO 1520
1530 TOKEN=185:A$=",X":GOSUB 1600
1540 TOKEN=184:A$=",Y":GOSUB 1600
1550 TOKEN=7:A$=" ":GOSUB 1600
1560 TOKEN=189:A$=",":GOSUB 1600
1570 TOKEN=193:A$=CHR$(34):GOSUB 1600
1580 TOKEN=182:A$=",X)":GOSUB 1600
1590 TOKEN=183:A$="),Y"
1600 TS(TOKEN)=C:TOKEN$(C)=A$
1610 TE(TOKEN)=LEN(TOKEN$)
1620 C=LEN(TOKEN$)+1:RETURN 
1630 REM 
1640 REM HEX CONVERSION
1650 REM 
1660 FOR A=0 TO 15:READ A$
1670 HEX(A)=ASC(A$):NEXT A:RETURN 
1680 C=INT(A/16):B=A-C*16
1690 PUT #2,HEX(C):PUT #2,HEX(B)
1700 RETURN 
1710 REM 
1720 REM READ DISK DIRECTORY
1730 REM 
1740 OPEN #3,6,0,"D:*.*":TRAP 1755
1750 INPUT #3,A$:? A$:GOTO 1750
1755 CLOSE #3:RETURN 
1760 REM 
1770 REM TOKEN TABLE
1780 REM 
1790 DATA 79,ADC,77,AND,84,ASL,68,BCC
1800 DATA 69,BCS,70,BEQ,71,BMI,72,BNE
1810 DATA 73,BPL,74,BVC,75,BVS,42,BIT
1820 DATA 43,BRK,44,CLC,45,CLD,46,CLI
1830 DATA 47,CLV,82,CMP,40,CPX,41,CPY
1840 DATA 34,DEC,48,DEX,49,DEY,78,EOR
1850 DATA 35,INC,50,INX,51,INY,33,JMP
1860 DATA 32,JSR,81,LDA,36,LDX,37,LDY
1870 DATA 86,LSR,52,NOP,76,ORA,53,PHA
1880 DATA 54,PHP,55,PLA,56,PLP,85,ROL
1890 DATA 87,ROR,83,SBC,59,SEC,60,SED
1900 DATA 61,SEI,80,STA,38,STX,39,STY
1910 DATA 62,TAX,63,TAY,64,TSX,65,TXA
1920 DATA 66,TXS,67,TYA,57,RTI,58,RTS
1930 DATA 21,BRA,90,DEA,91,INA,92,PHX
1940 DATA 93,PHY,94,PLX,95,PLY,89,STZ
1950 DATA 22,TRB,23,TSB,29,*=
1960 DATA 14,.END,26,;,19,.ORG,30,=
1970 DATA 20,.EQU,11,.BYTE,12,.SBYTE
1980 DATA 25,.CBYTE,13,.DBYTE,9,.WORD
1990 DATA 18,.DS,2,.ELSE,3,.ENDIF
2000 DATA 10,.ERROR,24,.FLOAT
2010 DATA 1,.IF,17,.INCLUDE,27,.LOCAL
2020 DATA 15,.OPT,8,.PAGE,28,.SET
2030 DATA 0,ERROR - ,4,.MACRO,5,.ENDM
2040 DATA 6,.TITLE,31,.=,16,.TAB
2050 DATA 190,#,187, ,134,$,133,$
2060 DATA 180, <,181, >,138,',159,[
2070 DATA 160,],146,+,149,/,148,*
2080 DATA 167,\,150,&,164,!,165,^
2090 DATA 152,=,156,>,157,<,158,-
2100 DATA 147,-,155,<>,154,>=,153,<=
2110 DATA 179, .OR ,197,NO ,201
2120 DATA LIST,178, .AND ,199
2130 DATA ERR,177, .NOT ,200
2140 DATA EJECT,176, .DEF ,198
2150 DATA OBJ,175, .REF ,203,MLIST
2160 DATA 204,CLIST,205,NUM,202,XREF
2170 DATA 192,(,186,),139,%$,141,*
2180 DATA 191,A,140,%,-1,XXX
2190 DATA 0,1,2,3,4,5,6,7,8,9
2200 DATA A,B,C,D,E,F
2210 END 

30

(130 odpowiedzi, napisanych Scena - 8bit)

To są pliki stokenizowane. Próbowałem przekonwertować je na zwykłe pliki tekstowe programem "DETOKEN.BAS", ale z obu otrzymuję niepełne listingi.

ostatnie przekonwertowane linie kodu obu plików (GR; PL)

4440  .BYTE ".......
2290  LDA 

Problem playera można próbować obejść ale dane muzyczki zapisane w GR nie da się odtworzyć.
Oczywiście problem może leżeć w źle przeprowadzonej konwersji, a pliki są pełne.

a gdyby tak zamiast ładować ten biedny bajt bezpośrednio skorzystać z małego programiku zapisującego do PORTB

Samo to nie pomoże.

dodać kod ustawiający PORTB do zapisu, bo w ten sposób co poniektóre programy bronią sie przed zmianą PORTB

Warto byłoby sprawdzić czy coś podobnego robi w pewnych warunkach Sparta. To przyznaję zupełnie nieznana dla mnie "okoliczność przyrody".

skąd wiadomo  jaka wartość ma zostać zapisana do PORTB, nie powinno skorzystać się z tablicy

Mogę tylko zapewnić że pomyłki z wyborem "niedziałającego" banku nie było, stąd wnioski na temat Sparty wydają mi się uprawnione.

próbuję zdiagnozować pewną przypadłość występującą w przypadku uruchomienia programu pod SDX, który nie korzysta z banku zajmowanego przez dos (czy sterownik do VBXE), lecz generuje problem z nieznanej mi przyczyny.

Jest prawdopodobne że chodzi o tą samą przyczynę problemu o której piszę w tym wątku (wg. mnie Sparta przełącza bank pamięci przed doczytaniem kolejnego bloku danych z zastanego banku na ten z którego korzysta sama a następnie na bank podstawowy który nie musi być tym samym co zastany).

Dzięki.

Pod dosem II+/D 6.1 przełączanie tym samym kodem działa bez zarzutu, więc tak czy inaczej problem wiążę ze Spartą.

    .or $D301
    .by bank
    .or $4000
; kod lub dane

Przy zastrzeżeniu że SPARTA rozpoznaje bank na który zostaje przełączona pamięć (dyskusja obecna w wątku: http://atariarea.krap.pl/forum/viewtopic.php?id=3032 ) powinno chyba działać.

Jeśli nie działa w warunkach Sparty bo pamięć jeszcze przed doczytaniem bloku danych przełączana jest kodem Sparty na bank $ff, to czy jest jakieś proste wyjście z takiej sytuacji (chodzi o pozostawienie przełączania banku pamięci w takiej prymitywnej formie z punktu widzenia Sparty)?

Sprawdzałem dla Sparty 4.42 rom (Altirra) w trybie Banked, pragram doczytywany z dysku w formacie ataridos (bootowane z dysku z config.sys: device: sparta, sio, ataridos).

34

(92 odpowiedzi, napisanych Fabryka - 8bit)

xxl: pobiera ze złego miejsca, ale zauważ że pisałem coś o przetasowaniu tych danych, więc potencjalnie procka może pobierać właściwe dane (i zaoszczędzić w najbardziej wewnętrznej pętli kolejnych 6 cykli, czyli razem już 10 na 41 wyjściowych, jeśli dobrze liczę)

to przetasowanie polegałoby na tym że:

x= ($3f and x)*4+int(x/$40)

np. x= $43
nowe x= 3*4+1= 13= $0d

35

(92 odpowiedzi, napisanych Fabryka - 8bit)

attrybuty
                lda <_build_atrybuty+1
                ldx >_build_atrybuty+1

                ldy #0
                clc

                sta _sp1
                adc #1
                sta _sp2

_copatrh        stx _sp1+1
                stx _sp2+1

_copatr         ldx $5800,y
                lda _ink_tab,x
                dta {sta 256,y}
_sp1            dta a(256+1)
                lda _paper_tab,x
                dta {sta 256,y}
_sp2            dta a(256+2)
                tya
                adc #4
                tay
                bne _copatr
                ldx _sp1+1
                inx
                lda _copatr+1
                adc #0
                and #3
                sta _copatr+1
                bne _copatrh

36

(92 odpowiedzi, napisanych Fabryka - 8bit)

Wydaje mi się że jeśli zawartość danych z _copart można przetasować to taką procedurę w pętli można przyspieszyć o 20%.

37

(41 odpowiedzi, napisanych Fabryka - 8bit)

tatqoo napisał/a:

To może emkaya też popytajcie. Odkąd pamiętam narzeka, że istniejące trackery są do bani (nie wykorzystują pełni możliwości pokeya).

W dyskusji która może zostać wydaje mi się niezauważona na forum atariage wypowiada się koder który zdaje się sugerować swoje zainteresowanie stworzeniem natywnego playera z postulowanymi przez emkaya możliwościami.

linki do 3. wpisów które miałyby o tym świadczyć:
http://www.atariage.com/forums/topic/16 … p__2099099
http://www.atariage.com/forums/topic/16 … p__2074488
http://www.atariage.com/forums/topic/16 … p__2075335

38

(19 odpowiedzi, napisanych Software, Gry - 8bit)

instrukcja mnozenia i/lub dzielenia
16-bitowy rejestr indeksowy

39

(20 odpowiedzi, napisanych Scena - 8bit)

>niestety nie wiem jak dokładnie ustawiać tempo

Z instrukcji wynika ze kombinacja CONTROL+Z pozwala przejsc do odpowiedniej kolumny w zapisie muzyczki.

>mniej więcej który instrument nie pasuje?

Zwrocil moja uwage instrument nr. 4 - "Pan Flute". Ale to moze byc subiektywne odczucie i jak mowie osoby nie zglebiajacej tej sfery tworczosci (muzykowania).

40

(20 odpowiedzi, napisanych Scena - 8bit)

Sim_Piko: dzieki za szczegolowe informacje odnoszace sie do muzyczek w RMT. Rowniez za podzielenie sie utworkiem wlasnej kompozycji.

Muzyczke w wersji oryginalnej (mp3) niestety wysluchalem tylko do ok. 30 sekundy, pozniej jakies klopoty ze strona. Stad trudno mi sie odniesc, chociaz poczatek brzmi calkiem interesujaco.
Wersja na atari jest w mojej ocenie troche monotonna (zauwazylem ze tempo jest wolniejsze) i nie wiem czy instrumentarium dobrane optymalnie (chodzi mi glownie o jeden instrument).
Tak to mniej wiecej postrzegam jako, zaznaczam, nie-muzyk.

Powodzenia i wytrwalosci w dalszym rozwijaniu zdolnosci muzycznych i koderskich.

41

(20 odpowiedzi, napisanych Scena - 8bit)

Sim_Piko: te utworki na RMT odtworzyles tez ze sluchu czy przekonwertowales/przepisales?

Mam nadzieje, ze uslysze w przyszlosci jakas Twoja wlasna kompozycje na Atari, bo przekonujesz tymi utworkami ze dysponujesz dobrym muzycznym sluchem.

Gdybys szukal jakiejs motywacji to zachecam do zajrzenia na forum atarionline do watku na temat utworu typu marsz wojenny z przeznaczeniem dla przygotowywanej przez ilmenita gry.

http://atarionline.pl/forum/comments.ph … sionID=224

42

(8 odpowiedzi, napisanych Fabryka - 8bit)

Rozegralem partyjke niebieskimi (przegrana) i mam wrazenie ze jednostka o (ogre) ale tez a (archer) pod koniec rozgrywki byly nie do zniszczenia. Atak na nie nie powodowal im najmniejszej szkody w przeciwienstwie do jednostki atakujacej. Moze to jakas wada programu na tym etapie projektowania, albo czegos tylko nie rozumiem.
Generalnie wyglada to bardzo ciekawie i oby port na atari byl rownie dobry (poza ewentualnymi niedopracowaniami o jakich wspominam oczywiscie).

Pomocnicy znajda sie pewnie, ale na poczatek proponuje okreslic konkretne potrzeby i zglosic to gdzies na forum. Ktos pewnie rekawice wowczas podejmie. Pozniej moze to przerodzic sie w bardziej stala wspolprace.

@ilmenit: nie obyło się bez błędu w prodce

instrukcja ADC <MAP jest niepotrzebna i jeśli adres mapki nie zaczyna się od $xx00, to skutkuje źle wyliczonym adresem

w ramach skracania zbędnego kodu dadam jeszcze, że jeśli adres MAP dzieli się w całości przez $400, to można pozbyć się kolejnych kilku istrukcji (wersja po zmianiach):

 lda >MAP/4
 sta adrMAP+2
 lda MAP_SIZE_Y
 asl @
 asl @
 asl @
 asl @
 rol adrMAP+2
 asl @
 rol adrMAP+2
 adc MAP_SiZE_X
 tax

adrMAP equ *+1
 lda MAP,x
 cmp #1
 rts

EDIT: przypadkowo zaglądając dziś do kopii tego kawałka kodu zauważyłem istotny błąd który chcę skorygować

w rozkazach rol adrMAP+2 w obu przypadkach i sta adrMAP 2-kę należy zastąpić 1-ką (*+1).

@mono: nie ma problemu przy wyjściu z procki przez exit z wartością 0 w shadow?

@ilmenit: poniżej jest wersja altermatywna (być może nieco szybsza) procki do wersji zaproponowanej przez mono

 lda #0
 sta ahY
 lda MAP_SIZE_Y
 asl @
 asl @
 asl @
 asl @        ; 16 * MAX_SIZE_Y max. % 1 1111:0000
 rol ahY
 asl @        ; 32 * MAX_SIZE_Y max. %11 1110:0000
 rol ahY
 adc MAP_SiZE_X
 adc <MAP
 tax        [sta adrMAP]

 lda ahY
 adc >MAP
 sta adrMAP+1

adrMAP equ *+1
 lda MAP,x    [lda MAP]
 cmp #1
 rts        [zn. C=0 -> shadow==true, c=1 * == false (dla TILEWALL=0)]

45

(13 odpowiedzi, napisanych Programowanie - 8 bit)

Mam nadzieję, że w temacie odzywam się po raz ostatni.

Znacznie udało mi się popracić wydajność procedury. Składam przy okazji samokrytykę że tyle wpisów zajęło mi dojście do takiej postaci kodu.

* generator opóźnienia liczonego w cyklach procesora
* dokładność do 1 cykla
* dopuszczalny zakres żądanego opóźnienia <17,65535>
* komunikacja z programem poprzez ustawienie timH i timL (str.0)


; tablica 4x3 'drobnych' ((0,2,4,6)+3) cykli opóźnień
; byt (gdzieś na str.0): operacje r/w

tdlay dta b($4c) ;jmp a
 dta b($05) ;ora b
 dta b($e6) ;inc b
 pha

 dta l(xa)
 dta b(byt)
 dta b(byt)
 pla

 dta h(xa)
 nop
 nop
 nop
 
; część przygotowawcza do umieszczenia w dowolnym miejscu
; po załadowaniu licznika żądanego opóźnienia

 lda timL
 sec
 sbc #9
 sta timL
 bcs *+4
 dec timH

 and #7
 lsr @
 php
 tax
 lda tdlay,x ;^1
 sta delay
 lda tdlay+4,x ;^1
 sta delay+1
 lda tdlay+8,x ;^1
 sta delay+2
 lda timH
 lsr @
 ror timL
 lsr @
 ror timL
 lsr @
 ror timL
 pha

;...


; tuż przed wywołaniem pętli opóźniającej
; znacznik C i rejestr X muszą pozostać niezmienione do momentu wywołania pętli

 pla
 tax
 plp

;...

; część właściwa - pętla opóźniająca

 bcs *+2 ;^1
delay equ *

 jmp *+3
 
xa dec timL
 bne *-2 ;^0

 dex
 bmi xx ;^1
 dec timL
 dec timL
 bne xa ! ;^0

xx equ * koniec pętli

* ^0: jeśli w wyniku wykonania rozkazu rejestr PC procesora musi przekroczyć stronę pamięci program (pętla opóźniająca) nie może właściwie działać (opóźnienie znacząco większe od oczekiwanego)
* ^1: jeśli w wyniku wykonania rozkazu przekroczona miałaby zostać granica strony pamięci do argumentu rozkazu SBC #9 należy dodać za każdym takim przypadkiem 1 (zmniejszy się w ten sposób zakres możliwego do wygenerowania opóźnienia na <17+n;65535>)

46

(13 odpowiedzi, napisanych Programowanie - 8 bit)

i od razu zgłaszam małą nieścisłość:

jeśli jeden z wierszy programu oznaczony na końcu ;^1 (BCS *+2) zasembluje się pod mało ciekawy adres (problem przekroczenia przez PC w wyniku jego wykonania granicy strony), nie wystarczy, jak to napisałem w komentarzu na końcu, jedynie dodać jeden do argunentu w stosownym, opisanym miejcu, ponieważ nie będziemy mieli gwarancji, że ten dodatkowy cykl zostanie w istocie zużyty (instrukcja skoku warunkowego może się nie wykonać "czynnie" w zależności od żądanej wartości opóźnienia)
dlatego w tym przypadku należy szczególnie zadbać o to, by adres asemblacji zapewnił uniknięcie sytuacji przekraczania przez rejestr PC granicy strony, jeśli oczywiście zależy nam na wygenerowaniu idealnego z postulowanym opóźnienia

47

(13 odpowiedzi, napisanych Programowanie - 8 bit)

Nieaktualne, ale postanowiłem doszlifować procedurkę. Projektowałem ją nie testując poprawności działania w żaden sposób (w istocie jest to z uwagi na subtelność zadania programu, raczej i trudne w praktyce). Nie daję więc najmniejszej gwarancji, że zamieszczany listing wygeneruje w istocie poprawnie działający program.

* generator opóźnienia liczonego w cyklach procesora
* dokładność do 1 cykla
* dopuszczalny zakres żądanego opóźnienia <82,65535>
* komunikacja z programem poprzez ustawienie timH i timL (str.0)


; tablica opóźnień dla końcowych 0-7 cykli
; byt (gdzieś na str.0): operacje r/w

tdlay dta b($4c) ;jmp a
 dta b($05) ;ora b
 dta b($e6) ;inc b
 pha

 dta l(xc)
 dta b(byt)
 dta b(byt)
 pla

 dta h(xc)
 nop
 nop
 nop
 
; część przygotowawcza do umieszczenia w dowolnym miejscu
; po załadowaniu licznika żądanego opóźnienia

 lda timL
 sec
 sbc #36+38
 sta timL
 bcs *+4
 dec timH
; ...

; część właściwa - pętla opóźniająca

 lda timL
 and #7
 lsr @
 tax
 lda tdlay,x ;^1
 sta delay
 lda tdlay+4,x ;^1
 sta delay+1
 lda tdlay+8,x ;^1
 sta delay+2

 bcs *+2 ;^1
delay equ *

 jmp *+3

 
xc lda timH
 lsr @
 ror timL
 lsr @
 ror timL
 lsr @
 ror timL
 sta timH
 jmp xa

xb nop
 dec timL
 dec timL
 dec timL

xa dec timL
 bne *-2 ;^0

 dec timH
 bpl xb ;^2


* ^0: jeśli w wyniku wykonania rozkazu rejestr PC procesora musi przekroczyć stronę pamięci program (pętla opóźniająca) nie może właściwie działać
* ^1: jeśli w wyniku wykonania rozkazu rejestr PC procesora musi przekroczyć stronę pamięci do argumentu rozkazu SBC #36+38 należy dodać za każdym takim przypadkiem 1
* ^2: jeśli w wyniku wykonania rozkazu rejestr PC procesora musi przekroczyć stronę pamięci do argumentu rozkazu SBC #74 należy dodać za każdym wykonaniem tego rozkazu 1 (cykle opóźnienia-(74+n)/2^11)

48

(13 odpowiedzi, napisanych Programowanie - 8 bit)

Zapomniałem dopisać:

że po podmianie fragmentu kodu z poprzedniego mojego postu, należy jeszcze poprawić wiersz:

SBC #39 na SBC #36 (konsekwencja tamtej zmiany)

oraz że jest to wersja kodu (chodzi mi teraz o wyliczenia cykli) zakładająca że skoki względne wewnątrz kodu pętli nie będą przekraczać granicy strony (co należy sprawdzić przy asemblacji)

jeśli etykieta xa miałaby mieć adres asemblacji $xxfe lub $xxff (tak przynajmniej mi się wydaje) procedura się "zgubi" i nie zadziała prawidłowo

jeśli etykieta xb miałaby mieć adres asemblacji o stronę niższą od adresu asemblacji ostatniego wiersza kodu pętli ( BPL XB) należałoby jeszcze zamienić wiersz kodu SBC #36 na SBC #37 (tak przynajmniej mi się wydaje)

49

(13 odpowiedzi, napisanych Programowanie - 8 bit)

Można poprawić ten fragment kodu gdzie mamy trzy pary rozkazów:

 lsr timH
 ror timL

na ten fragment, co pozwoli obniżyć granicę tolerancji dla wartości opóźnienia z obecnej o 3 cykle na 44 (39+8-3):

 lda timH
 lsr @
 ror timL
 lsr @
 ror timL
 lsr @
 ror timL
 sta timH

50

(13 odpowiedzi, napisanych Programowanie - 8 bit)

Poniższy kod powinien spełniać następujące założenia (jeśli nie ma blędów):
- musi być wywoływany dla opóźnienia wynoszącego co najmniej 47 (39+8) cykli,
- dokładność opóźnienia do 7 cykli niedocyklowanych (za krótkiego opóźninia).

; część przygotowująca

 lda timL
 sec
 sbc #39 ;55
 sta timL
 bcs *+4
 dec timH
; ...



; część właściwa - pętla opóźniająca
 
; ldx #3
xc lsr timH
 ror timL
; dex
; bne xc
; beq xa

 lsr timH *
 ror timL *
 lsr timH *
 ror timL *
 jmp xa

xb nop
 dec timL
 dec timL
 dec timL

xa dec timL
 bne *-2

 dec timH
 bpl xb