Спасибо за подсказку. Работает, хотя наглядность, конечно, при сравнении пропала. Но для уже написанного особой разницы нет.
Вид для печати
Существует ли какой-нибудь метод, который позволяет автоматически развернуть все макросы, подставить все данные и удалить из несработавшие условия?
Исходный макрос:
Код:; LD reg,(IX+d)
macro macro_ld_reg_ix_d reg, data, no_stack
if reg != 0 ; A
ld (.tmp + 1), a
endif
if no_stack == 1 || reg == 5 || reg == 6 ; || H || L
if reg != 5
ld a, h
ld (TMP1 + 1), a
endif
if reg != 6
ld a, l
ld (TMP1), a
endif
else
push hl
endif
ld hl, (rIX)
if reg == 1 || reg == 2 ; B || C
if no_stack == 1
ld a, d
ld (TMP2 + 1), a
ld a, e
ld (TMP2), a
else
push de
endif
ld de, data
else
if no_stack == 1
ld a, b
ld (TMP2 + 1), a
ld a, c
ld (TMP2), a
else
push bc
endif
ld bc, data
endif
if reg == 1 || reg == 2 ; B || C
add hl, de
else
add hl, bc
endif
if reg == 1 || reg == 2 ; B || C
if no_stack == 1
ld a, (TMP2 + 1)
ld d, a
ld a, (TMP2)
ld e, a
else
pop de
endif
else
if no_stack == 1
ld a, (TMP2 + 1)
ld b, a
ld a, (TMP2)
ld c, a
else
pop bc
endif
endif
ld reg, (hl)
if reg == 0 ; A
ld (.tmp + 1), a
endif
if no_stack == 1 || reg == 5 || reg == 6 ; || H || L
if reg != 5
ld a, (TMP1 + 1)
ld h, a
endif
if reg != 6
ld a, (TMP1)
ld l, a
endif
else
pop hl
endif
.tmp ld a, 0
endm
А нужно, чтобы он развернулся, подставились все необходимые значения и убрались все несработавшие условия. То есть, чтобы в итоге в тексте вместо
macro_ld_reg_ix_d A,99-100,0
нарисовалось такое:
Код:; macro_ld_reg_ix_d A,99-100,0
push hl
ld hl, (rIX)
push bc
ld bc, 99-100
add hl, bc
pop bc
ld a, (hl)
pop hl
;---------------------------------------
В общем, отвечаю сам себе, вдруг ещё кому-нибудь пригодится.
1. Создал листинг с помощью ключа --lst
2. Загрузил его в Excel и там разбил на колонки.
3. Удалил следующие строки, удовлетворяющие следующим условиям по двум колонкам:
- Пустой код && >
- Код ~ && >
- Не пустой код && Пустой текст
4. Скопировал колонку с текстом в редактор.
В редакторе дополнительно вручную обработал вызов макросов и локальных меток, которые начинаются с точки.
а потом искать почему неправильно работает, а С то улетел
Я, естественно, сравнил получаемый бинарник до подобного преобразования и после него. Всё совпадает байт в байт.
Я про то что комманда ld R,(ix+D) на афектит флаг С, а замена еще как, да и не только С. Не знаю как часто, но думаю подобные ситуации встречаются.
Не знаю, как вы кавычки пробовали. Вот я попробовал:
Все нормально выполняется. Первое условие выполнилось, второе - нет, все корректно. Хотя я у этого кросс-ассемблера заметил какую-то лажу в приоритетах операций. Иногда довольно странные скобки приходится ставить.Код:macro instr reg1, reg2
if reg1 == "A"
DISPLAY "A"
; some code
if reg2 == "H"
DISPLAY "H"
; some code
endm
instr "A", "C"
Ну и да, у вас второй иф вложен в первый, ENDIFов нет.Код:SjASMPlus Z80 Cross-Assembler v1.21.0 (https://github.com/z00m128/sjasmplus)
Pass 1 complete (0 errors)
Pass 2 complete (0 errors)
> A
macro.asm(11): error: [IF] No ENDIF
macro.asm(15): ^ emitted from here
macro.asm(11): error: [IF] No ENDIF
macro.asm(15): ^ emitted from here
Pass 3 complete
Errors: 2, warnings: 0, compiled: 23 lines, work time: 0.000 seconds
Или вы хотели в instr именно без кавычек писать имена регистров?
Кавычки в параметрах макроса по лексике не подходили.
Видимо просто схематично изобразил условия, ENDIFы в ' ; some code'е спрятались ))
- - - Добавлено - - -
Ну ещё, если не юзать метки, то можно через lua решить вопрос, но телодвижений больше ))
Если честно, вы немного... непонятно формулируете вопрос и свою задачу, мне она не очень понятна. Впечатление, что проблемы именно с формулированием.
Вызов макроса формирует код. В теле макроса у вас выполняются или не выполняются отдельные условия, формируется код, размещенный в сработавших ветвях, код из несработавших ветвей не формируется. Что значит "метод, который позволяет автоматически развернуть все макросы, подставить все данные и удалить из несработавшие условия"? Откуда чего вы хотите удалить?! Я вас не понимать.
Добавил:
и в конце:Код:DEVICE ZXSPECTRUM48
ORG 32768
A EQU 0
(А почему я это должен писать?!)Код:rIX DEFW 0
В итоге, все нормально скомпилировалось, ваш макрос при таком вызове macro_ld_reg_ix_d A,99-100,0 сформировал вот такой код:
И что вы хотите? Поконкретнее плз. Потому чтоКод:PUSH HL
LD HL,(#8012) ; это адрес вашей переменной rIX
PUSH BC
LD BC,#FFFF ; это ваша минус единица, 99-100=-1
ADD HL,BC
POP BC
LD A,(HL)
LD (#8011),A ; это не то, что вы хотели, но таков ваш макрос:
;if reg == 0 ; A
; ld (.tmp + 1), a
;endif
; исправляйте его, если хотите что-то другое
POP HL
LD A,0 ; это тоже не то, что вам нужно, но... вы же это написали в макросе
именно это и произошло.
- - - Добавлено - - -
Какие константы? Это реальные байты. Я не понимаю, зачем использовать для этого реальные байты памяти... Есть переменные. Вон я пример привел с EQU, определил A. Можете теперь сравнивать с A, а не с нулем. Ну вообще конечно плохо пересекаться с именами регистров, но если очень уж хочется, то можно. Но зачем?!
Ну и я просто не вполне понимаю задачу, которую вы делаете. Я так понял, вы хотите реализовать инструкцию работы с индексным регистром, обходясь регистрами HL и BC, этим обеспечив совместимость с другим процессором без поддержки таких инструкций. Вы хотите какие-то исходники преобразовать в такой вот измененный код, переассемблировать, что-то куда-то портировать? На какую машину? Что и откуда вам нужно удалить?!
И да, вам очень правильно указали, что ADD влияет на флаги, в отличие от загрузки в память/из памяти по адресу из индексного регистра плюс-минус смещение, вам придется об этом позаботиться.
Регистры и регистровые пары логичнее было бы нумеровать так, как они пронумерованы в опкодах, чтобы затем по возможности по приходящему значению вычислять нужный опкод, а не городить многоэтажные IFы.
Ну вот я как раз и говорю о том, что у автора вопроса проблемы с формулированием целей и задачи. Чтобы его понять, приходится какое-то время вникать в его макрос, пытаться понять, что он там настроил, да и вообще, что у него в голове за поток сознания, а не просто прочитать комментарий, написанный нормальным языком, мол стоит задача такая-то такая-то, проблема такая-то такая-то.
Посмотрел, что там у Интела с макросами, попробовал написать так же и тут, и это почти заработало, но, поскольку таких имен ни переменных, ни лейблов не существует, там специальный синтаксис для получения значений для сравнения таких вот псевдопеременных из имен регистров, и специальная директива для получения типа входящей переменной, чего в sjasm вроде бы нет. Не помешало бы добавить. Я немного взломал систему, если можно так выразиться, получилось вот так:
Это почти работает, что-то можно сравнивать, но, понятное дело, только с теми регистрами и регистровыми парами, которые умещаются в 16-чную систему счисления. HL, SP, IX, IY, штрихи всякие в пролете. Но это чисто поржать, я не рекомендую так это использовать, т.к. явно тут вылезли какие-то недоработки в компиляторе, которые нужно устранить.Код:macro load8 l8, h8
display $h8
display $l8
ld l8, h8
endm
macro load16 l16, h16
display $h16
display $l16
if $h16 == $AF
display "h16=AF"
endif
if $l16 == $BC
display "l16=BC"
endif
push h16
pop l16
endm
load8 B,C
load16 DE,AF
Ну не знаю, может Ped7g прокомментирует, может быть там есть возможности, о которых мы не знаем.
Upd: Хотя вот так все работает:
Код:B equ 0
C equ 1
D equ 2
E equ 3
H equ 4
L equ 5
A equ 7
b equ 0
c equ 1
d equ 2
e equ 3
h equ 4
l equ 5
a equ 7
BC equ 0
DE equ 1
HL equ 2
SP equ 3
AF equ 3
bc equ 0
de equ 1
hl equ 2
sp equ 3
af equ 3
macro ld8 dst, src
display "LD8"
display src
display dst
if dst == H
display "dst = reg H"
endif
ld dst,src
ld a,b ; это проставит инструкцию с реальными регистрами A и B
endm
ld8 B,C
ld8 H,E
И никаких костылей, или байтов в памяти.Код:SjASMPlus Z80 Cross-Assembler v1.21.0 (https://github.com/z00m128/sjasmplus)
Pass 1 complete (0 errors)
Pass 2 complete (0 errors)
> LD8
> 0x0001
> 0x0000
> LD8
> 0x0003
> 0x0004
> dst = reg H
Pass 3 complete
Errors: 0, warnings: 0, compiled: 208 lines, work time: 0.000 seconds