forum speccy.pl
ZX Spectrum => PROGRAMOWANIE => Wątek zaczęty przez: coberr w 2016.02.09, 00:59:00
-
mam problem z tym draniem i już przyznam szczerze nie wiem czego sie chwycić. Może coś źle doczytalem.
Probuje stworzyć przykładowe makro :
MACRO TEST ; polecenie "macro" umieszczone w polu dyrektywy
.
.
; tu znajduje się wpisany kod
.
.
ENDM
; dalsza czesc programu + wywołanie makra :
.
.
.
TEST ; nazwa makra równiez umieszczona w polu dyrektywy
.
.
I jest problem - PASMO niby nie zgłasza błędu ale też nie widzę kodu makra w pliku wyjściowym (bin, hex - jak zwał tak zwał)
kompilator zachowuje sie tak - jakby nie widział polecen wywołania makra (ani też samego makra)
może coś doradzicie?
EDIT:
WYMĘCZYŁEM TEMAT - WSZYSTKO JEST O.K. - przez to siedzenie pomyliłem pliki - zamiast modyfikowac plik hex - kompilator modyfikował plik bin :). Moglem sobie sprawdzać... :D
jednak mimo wszystko cos jest chyba nie tak...
Przy wywołaniu jednego makra więcej niz jeden raz - pasmo wywala błąd.
Jezeli w samym makrze znajdują się jakieś nazwane pętle, podprogramy cokolwiek - np:
MACRO PAUZA
LD E,04H
T1: LD B,0FFH
T2: LD D,0FFH
T3: DEC D
JP NZ,T3
DEC B
JP NZ,T2
DEC E
JP NZ,T1
ENDM
DOtyczy to zwłaszcza linii z : t1,t2,t3.
Pierwsze wywołanie makra pauza - pasmo jakoś przetrawi..
Kolejnych już nie.
co to może być?
chcialbym taki fragment kodu wykonac kilka razy w programie (nie zalezy mi na jego prędkości a o uzyskanie opóźnienia w kilku miejscach programu po prostu)
-
mam problem z tym draniem i już przyznam szczerze nie wiem czego sie chwycić. Może coś źle doczytalem.
Probuje stworzyć przykładowe makro :
MACRO TEST ; polecenie "macro" umieszczone w polu dyrektywy
.
.
; tu znajduje się wpisany kod
.
.
ENDM
; dalsza czesc programu + wywołanie makra :
.
.
.
TEST ; nazwa makra równiez umieszczona w polu dyrektywy
.
.
I jest problem - PASMO niby nie zgłasza błędu ale też nie widzę kodu makra w pliku wyjściowym (bin, hex - jak zwał tak zwał)
kompilator zachowuje sie tak - jakby nie widział polecen wywołania makra (ani też samego makra)
może coś doradzicie?
pasmo -v - moze cos wiecej wypisze przy asemblacji.
-
Nie wiem jak jest w PASMO, ale w innych assemblerach wstawianie etykiet dla skoków do makra jest niemożliwe albo bardzo trudne.
W ASM51 jest możliwość wywołania makra z parametrem.
Wtedy robi się sztuczkę, gdzie jako jeden z parametrów wstawia się bieżący adres wywołania makra, a etykiety mają generowane nazwy na podstawie tego adresu.
Wtedy linker każdą etykietę widzi jako unikalną i nie ma problemów.
Wygląda to mniej więcej tak:
L_PS2_WAIT_FOR MACRO cIn,aErr,SFX ; helper for PS2_WAIT_FOR
ps2_wait_for_loop_&SFX:
acall ps2in ; call routine {ps2svc.sub}
jc ps2_wait_for_test_&SFX ; if data then check
jnb PS2Error,ps2_wait_for_loop_&SFX ; wait if not timeout
ps2_wait_for_err_&SFX:
ajmp aErr ; jump if fail
ps2_wait_for_test_&SFX:
cjne a,#cIn,ps2_wait_for_err_&SFX ; test received data
ENDM
;-------------------------------------------------------------------------------
PS2_WAIT_FOR MACRO cIn,aErr ; wait for specified PS/2 data
L_PS2_WAIT_FOR cIn,aErr,%$ ; auxiliary submacro
ENDM
a po zlinkowaniu:
=1 723 +1 PS2_WAIT_FOR 0FAh,mi_err ; in FA - mouse aknowledge
=1 724 +2 L_PS2_WAIT_FOR 0FAh,mi_err,%$ ; auxiliary submacro
0196 =1 725 +2 ps2_wait_for_loop_406:
0196 118F =1 726 +2 acall ps2in ; call routine {ps2svc.sub}
0198 4005 =1 727 +2 jc ps2_wait_for_test_406 ; if data then check
019A 3072F9 =1 728 +2 jnb PS2Error,ps2_wait_for_loop_406 ; wait if not timeout
019D =1 729 +2 ps2_wait_for_err_406:
019D 8182 =1 730 +2 ajmp mi_err ; jump if fail
019F =1 731 +2 ps2_wait_for_test_406:
019F B4FAFB =1 732 +2 cjne a,#0FAh,ps2_wait_for_err_406 ; test received data
-
Zaglądając do dokumentacji rozwiązania są dwa... Albo określamy wprost symbole jako lokalne
LOCAL
Marks identifiers as local to the current block. The block may be a MACRO, REPT, IRP or PROC directive, the local ambit ends in the corresponding ENDM or ENDP directive. The ambit begins at the LOCAL directive, not at the beginning of the block, take care with that.
If several LOCAL declations of the same identifier are used in the same block, only the first has effect, the others are ignored.
Czyli:
org $8000
test macro ile
local t1
ld b,ile
t1: nop
djnz t1
endm
test 10
test 20
test 30
Albo podajemy jako parametr --alocal i wtedy wszystkie etykiety zaczynające się na _ są traktowane jako lokalne
--alocal
Use autolocal mode. In this mode all labels that begins with '_' are locals. See the chapter about labels for details.
Czyli :
org $8000
test macro ile
ld b,ile
_t1: nop
djnz _t1
endm
test 10
test 20
test 30
i wtedy np:
pasmo --alocal --bin test.asm test.bin
-
Bardzo wam dziękuję za pomoc :)
to juz mnie sie troche rozjasniło pod deklem :)
własnie przy assemblerze 8051 jakoś pamiętam - ze nie miałem aż tak wielkich problemów z dodawaniem makr. A tu pojawił sie kłopotek :)
narazie poradzilem sobie w ten sposób, ze powstawialem niezbędne opoznienia do programu tam gdzie były potrzebne w kilkunastu miejscach :) (nie mogę skorzystać ze stosu wywołań podprogramów itp).
Przeanalizuję wszystko i dam znać o efektach :)
-
Dopiszę się, podobny problem.
Chcę wstawić do kodu blok NOP o długości równej DELAY, a po nim następny blok.
DELAY musi być zdefiniowana jako etykieta a nie liczba, bo jest używana też w innych miejscach kodu.
Przygotowałem plik block0.bin, 256 B długi, składający się z samych NOP, ale ma być on "przycięty"
Pasmo wyrzuca błąd przy takiej próbie:
DELAY: equ 64
...
NOPSPACE:
incbin block0.bin ;space filled with zero
DATA:
org nopspace+delay
incbin data.bin
Zrobione. Dla Pasmo NOPSPACE i nopspace to dwie różne etykiety. Poprawiłem na małe litery i poszło.
Zostawiam post. Może da się prościej, właśnie przez makro. Jakieś REPT ... ENDM ?
-
Pasmo nie lubi nakładających się bloków.
Skorzystaj z pseudopolecenia REPT
delay equ 66
org 0
jp gdziestam
rept delay
nop
endm
gdziestam:
ret
-
Nie działało, bo etykieta raz była napisana dużymi literami, raz małymi.
Z REPT teraz też zrobił. Obie wersje działają, ale z REPT bardziej profesjonalnie :)